Skip to content

Commit 8c08759

Browse files
committed
Mock new methods on an existing mock
1 parent 9710e17 commit 8c08759

File tree

3 files changed

+60
-24
lines changed

3 files changed

+60
-24
lines changed

README.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,47 +35,57 @@ Yuck!
3535
Here is how to write it with EasyMock:
3636

3737
```php
38-
$mock = EasyMock::mock('My\Class', array(
38+
$mock = EasyMock::mock('My\Class', [
3939
'sayHello' => 'Hello',
40-
));
40+
]);
4141
```
4242

4343
### Features
4444

4545
You can mock methods so that they return values:
4646

4747
```php
48-
$mock = EasyMock::mock('My\Class', array(
48+
$mock = EasyMock::mock('My\Class', [
4949
'sayHello' => 'Hello',
50-
));
50+
]);
5151
```
5252

5353
Or so that they use a callback:
5454

5555
```php
56-
$mock = EasyMock::mock('My\Class', array(
56+
$mock = EasyMock::mock('My\Class', [
5757
'sayHello' => function ($name) {
5858
return 'Hello ' . $name;
5959
},
60-
));
60+
]);
6161
```
6262

6363
You can also have methods throw exceptions by providing an `Exception` instance:
6464

6565
```php
66-
$mock = EasyMock::mock('My\Class', array(
66+
$mock = EasyMock::mock('My\Class', [
6767
'sayHello' => new \RuntimeException('Whoops'),
68-
));
68+
]);
69+
```
70+
71+
It is possible to call the `mock()` method again on an existing mock:
72+
73+
```php
74+
$mock = EasyMock::mock('My\Class');
75+
76+
$mock = EasyMock::mock($mock, [
77+
'sayHello' => 'Hello',
78+
]);
6979
```
7080

7181
### What if?
7282

7383
If you want to use assertions or other PHPUnit features, just do it:
7484

7585
```php
76-
$mock = EasyMock::mock('My\Class', array(
86+
$mock = EasyMock::mock('My\Class', [
7787
'sayHello' => 'hello',
78-
));
88+
]);
7989

8090
$mock->expects($this->once())
8191
->method('sayGoodbye')

src/EasyMock.php

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use PHPUnit_Framework_MockObject_Generator;
66
use PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
7-
use PHPUnit_Framework_MockObject_MockObject;
7+
use PHPUnit_Framework_MockObject_MockObject as MockObject;
88

99
/**
1010
* Generates mock objects.
@@ -19,23 +19,18 @@ class EasyMock
1919
* Methods not specified in $methods will be mocked to return null (default PHPUnit behavior).
2020
* The class constructor will *not* be called.
2121
*
22-
* @param string $classname The class to mock.
22+
* @param string $classname The class to mock. Can also be an existing mock to mock new methods.
2323
* @param array $methods Array of values to return, indexed by the method name.
2424
*
25-
* @return PHPUnit_Framework_MockObject_MockObject
25+
* @return \PHPUnit_Framework_MockObject_MockObject
2626
*/
2727
public static function mock($classname, array $methods = array())
2828
{
29-
$mockGenerator = new PHPUnit_Framework_MockObject_Generator();
30-
31-
/** @var PHPUnit_Framework_MockObject_MockObject $mock */
32-
$mock = $mockGenerator->getMock(
33-
$classname,
34-
array(),
35-
array(),
36-
'',
37-
false
38-
);
29+
if ($classname instanceof MockObject) {
30+
$mock = $classname;
31+
} else {
32+
$mock = self::createMock($classname);
33+
}
3934

4035
foreach ($methods as $method => $return) {
4136
self::mockMethod($mock, $method, $return);
@@ -44,7 +39,7 @@ public static function mock($classname, array $methods = array())
4439
return $mock;
4540
}
4641

47-
private static function mockMethod(PHPUnit_Framework_MockObject_MockObject $mock, $method, $return)
42+
private static function mockMethod(MockObject $mock, $method, $return)
4843
{
4944
$methodAssertion = $mock->expects(new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount)
5045
->method($method);
@@ -57,4 +52,21 @@ private static function mockMethod(PHPUnit_Framework_MockObject_MockObject $mock
5752
$methodAssertion->willReturn($return);
5853
}
5954
}
55+
56+
/**
57+
* @param string $classname
58+
* @return MockObject
59+
*/
60+
private static function createMock($classname)
61+
{
62+
$mockGenerator = new PHPUnit_Framework_MockObject_Generator();
63+
64+
return $mockGenerator->getMock(
65+
$classname,
66+
array(),
67+
array(),
68+
'',
69+
false
70+
);
71+
}
6072
}

tests/MockClassTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,18 @@ public function should_mock_existing_method_to_throw_exception()
8888
));
8989
$mock->foo();
9090
}
91+
92+
/**
93+
* @test
94+
*/
95+
public function should_mock_new_methods_on_existing_mock()
96+
{
97+
/** @var ClassFixture $mock */
98+
$mock = EasyMock::mock('EasyMock\Test\Fixture\ClassFixture');
99+
$mock = EasyMock::mock($mock, array(
100+
'foo' => 'bar',
101+
));
102+
103+
$this->assertSame('bar', $mock->foo());
104+
}
91105
}

0 commit comments

Comments
 (0)