-
Notifications
You must be signed in to change notification settings - Fork 4
/
TestHookTest.php
81 lines (73 loc) · 2.42 KB
/
TestHookTest.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
/**
* The TestCase shows how first only a brittle test and a loose assertion
* can be made over the result. With proper isolation, the assertion becomes
* an equality: at the same time TestableTimeBox isn't going to break client
* code where UntestableTimeBox was used, because we only changed an internal
* detail and not the public Api (like its constructor).
*/
class TestHookTest extends PHPUnit_Framework_TestCase
{
public function testTheUntestableTimeBoxWithASmokeTest()
{
$box = new UntestableTimeBox();
$this->assertRegexp('/<div(.*)<\/div>/', $box->__toString());
}
public function testTheTestableTimeBoxWithAUnitTest()
{
$box = new TestSubclassOfTestableTimeBox(0000001);
$this->assertEquals('<div class="current_timestamp">1970-01-01</div>', $box->__toString());
}
public function testTheTestableTimeBoxWithAUnitTestAndAPartialGeneratedMock()
{
$box = $this->getMock('TestableTimeBox', array('currentTime'));
$box->expects($this->any())
->method('currentTime')
->will($this->returnValue(0000001));
$this->assertEquals('<div class="current_timestamp">1970-01-01</div>', $box->__toString());
}
}
/**
* The original SUT: there is no way to fully test it due to the global state
* introduced by time().
*/
class UntestableTimeBox
{
public function __toString()
{
return '<div class="current_timestamp">' . date('Y-m-d', time()) . '</div>';
}
}
/**
* The SUT with a really small refactoring, which does not break its Api.
* Of course in reality it would have the same name of the original SUT...
*/
class TestableTimeBox
{
public function __toString()
{
return '<div class="current_timestamp">' . date('Y-m-d', $this->currentTime()) . '</div>';
}
protected function currentTime()
{
return time();
}
}
/**
* A Test-Specific Subclass that overrides the Test Hook. This is *not* part
* of production code.
* You add all these lines of code specific just in order to run a simple test:
* the payback you get is the shorter test length. A next step could be to
* inject a simple collaborator wrapping time().
*/
class TestSubclassOfTestableTimeBox extends TestableTimeBox
{
public function __construct($currentTime)
{
$this->currentTime = $currentTime;
}
protected function currentTime()
{
return $this->currentTime;
}
}