27
loading...
This website collects cookies to deliver better user experience
TL;DR: Don't write methods with the only purpose of being used in your tests.
Encapsulation Violation.
Bad interfaces
Coupling
Don't break encapsulation.
Test must be in full control.
If you cannot control your object, you are coupled. Decouple them!
<?
class Hangman {
private $wordToGuess;
function __construct() {
$this->wordToGuess = getRandomWord();
//Test is not in control of this
}
public function getWordToGuess(): string {
return $this->wordToGuess;
}
}
class HangmanTest extends TestCase {
function test01WordIsGuessed() {
$hangmanGame = new Hangman();
$this->assertEquals('tests', $hangmanGame->wordToGuess());
//how can we make sure the word is guessed?
}
}
<?
class Hangman {
private $wordToGuess;
function __construct(WordRandomizer $wordRandomizer) {
$this->wordToGuess = $wordRandomizer->newRandomWord();
}
}
class MockRandomizer implements WordRandomizer {
function newRandomWord(){
return 'tests';
}
}
class HangmanTest extends TestCase {
function test01WordIsGuessed() {
$hangmanGame = new Hangman(new MockRandomizer());
$this->assertFalse($hangmanGame->wordWasGuessed());
$hangmanGame->play('t');
$this->assertFalse($hangmanGame->wordWasGuessed());
$hangmanGame->play('e');
$this->assertFalse($hangmanGame->wordWasGuessed());
$hangmanGame->play('s');
$this->assertTrue($hangmanGame->wordWasGuessed());
//We just test behavior
}
}
Nothing makes a system more flexible than a suite of tests.