Skip to content

Commit 95c52e2

Browse files
committed
Added EasyMock::spy() to assert a method is called at least once
1 parent 8c08759 commit 95c52e2

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ $mock = EasyMock::mock('My\Class', [
4040
]);
4141
```
4242

43+
What if you want to assert that the method is called once (i.e. `$mock->expect($this->once())`)? Use `spy()` instead:
44+
45+
```php
46+
$mock = EasyMock::spy('My\Class', [
47+
'sayHello' => 'Hello',
48+
]);
49+
```
50+
4351
### Features
4452

4553
You can mock methods so that they return values:

src/EasyMock.php

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace EasyMock;
44

55
use PHPUnit_Framework_MockObject_Generator;
6-
use PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
6+
use PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount as AnyInvokedCount;
7+
use PHPUnit_Framework_MockObject_Matcher_Invocation as InvocationMatcher;
8+
use PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce as InvokedAtLeastOnce;
79
use PHPUnit_Framework_MockObject_MockObject as MockObject;
810

911
/**
@@ -33,15 +35,43 @@ public static function mock($classname, array $methods = array())
3335
}
3436

3537
foreach ($methods as $method => $return) {
36-
self::mockMethod($mock, $method, $return);
38+
self::mockMethod($mock, $method, new AnyInvokedCount, $return);
3739
}
3840

3941
return $mock;
4042
}
4143

42-
private static function mockMethod(MockObject $mock, $method, $return)
44+
/**
45+
* Mock the given class by spying on method calls.
46+
*
47+
* This is the same as EasyMock::mock() except this assert that methods are called at
48+
* least once.
49+
*
50+
* @see mock()
51+
*
52+
* @param string $classname The class to mock. Can also be an existing mock to mock new methods.
53+
* @param array $methods Array of values to return, indexed by the method name.
54+
*
55+
* @return \PHPUnit_Framework_MockObject_MockObject
56+
*/
57+
public static function spy($classname, array $methods = array())
58+
{
59+
if ($classname instanceof MockObject) {
60+
$mock = $classname;
61+
} else {
62+
$mock = self::createMock($classname);
63+
}
64+
65+
foreach ($methods as $method => $return) {
66+
self::mockMethod($mock, $method, new InvokedAtLeastOnce, $return);
67+
}
68+
69+
return $mock;
70+
}
71+
72+
private static function mockMethod(MockObject $mock, $method, InvocationMatcher $invocation, $return)
4373
{
44-
$methodAssertion = $mock->expects(new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount)
74+
$methodAssertion = $mock->expects($invocation)
4575
->method($method);
4676

4777
if (is_callable($return)) {

tests/MockClassTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,14 @@ public function should_mock_new_methods_on_existing_mock()
102102

103103
$this->assertSame('bar', $mock->foo());
104104
}
105+
106+
/**
107+
* @test
108+
*/
109+
public function should_allow_to_spy_method_calls()
110+
{
111+
$mock = EasyMock::spy('EasyMock\Test\Fixture\ClassFixture', array(
112+
'foo' => 'bar',
113+
));
114+
}
105115
}

0 commit comments

Comments
 (0)