-
Notifications
You must be signed in to change notification settings - Fork 4
/
TestSpyTest.php
115 lines (99 loc) · 3.19 KB
/
TestSpyTest.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<?php
class TestSpyTest extends PHPUnit_Framework_TestCase implements Mailer, Db
{
/**
* Other expectations would be simple to check with generated Mocks,
* but order of calls on different object is not in PHPUnit.
* The same Self-Shunting setup can be used in other tests too.
*/
public function testSendsAMailAfterUserCreationViaSelfShunting()
{
// remember, Db and Mailer would be two different objects in production
$sut = new UserDao($this, $this);
$sut->createUser(array('mail' => '[email protected]', 'nickname' => 'johndoe'));
$this->assertEquals(array('executeQuery', 'mail'), $this->order);
}
private $order = array();
private $queries = array();
public function executeQuery($query, array $params)
{
$this->order[] = 'executeQuery';
$this->queries[] = $query;
}
private $mails = array();
public function mail($to, $subject, $object)
{
$this->order[] = 'mail';
$this->mails[] = array('to' => $to,
'subject' => $subject,
'object' => $object);
}
public function testInnerTestDoubleArrayObject()
{
$parts = new ArrayObject();
$receiver = $this->getMock('Receiver');
$receiver->expects($this->any())
->method('definePart')
->will($this->returnCallback(function($amount) use ($parts) {
$parts[] = $amount;
}));
$sut = new RandomDivider($receiver);
$sut->divide(10);
$this->assertEquals(10, array_sum($parts->getArrayCopy()));
}
public function testInnerTestDoubleArrayPassedByReference()
{
$parts = array(); // an array would not be passed by handler by default
$receiver = $this->getMock('Receiver');
$receiver->expects($this->any())
->method('definePart')
->will($this->returnCallback(function($amount) use (&$parts) { // but we can pass it by reference
$parts[] = $amount;
}));
$sut = new RandomDivider($receiver);
$sut->divide(10);
$this->assertEquals(10, array_sum($parts));
}
}
interface Mailer
{
public function mail($to, $subject, $object);
}
interface Db
{
public function executeQuery($query, array $params);
}
class UserDao
{
private $db;
private $mailer;
public function __construct(DB $db, Mailer $mailer)
{
$this->db = $db;
$this->mailer = $mailer;
}
public function createUser(array $userDetails)
{
// internally it would use PDO
$this->db->executeQuery("INSERT INTO users ...", $userDetails);
$this->mailer->mail($userDetails['mail'], 'You have been registered on example.com', '...');
}
}
interface Receiver
{
public function definePart($amount);
}
class RandomDivider
{
private $receiver;
public function __construct(Receiver $receiver)
{
$this->receiver = $receiver;
}
public function divide($total)
{
$part = ceil(rand() * $total);
$this->receiver->definePart($part);
$this->receiver->definePart($total - $part);
}
}