Skip to content

Commit

Permalink
Merge e0b8627 into 9113ef7
Browse files Browse the repository at this point in the history
  • Loading branch information
kenjis committed Jul 15, 2020
2 parents 9113ef7 + e0b8627 commit ac345dc
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 14 deletions.
43 changes: 33 additions & 10 deletions application/tests/_ci_phpunit_test/CIPHPUnitTestDouble.php
Expand Up @@ -32,30 +32,53 @@ public function __construct(PHPUnit_Framework_TestCase $testCase)
*
* @param string $classname
* @param array $params [method_name => return_value]
* @param mixed $constructor_params false: disable construntor, array: construntor params
*
* @param mixed $constructor_params false: disable constructor, array: constructor params
*
* @return mixed PHPUnit mock object
*/
public function getDouble($classname, $params, $constructor_params = false)
{
$methods = array_keys($params);

// `disableOriginalConstructor()` is the default, because if we call
// construnctor, it may call `$this->load->...` or other CodeIgniter
// constructor, it may call `$this->load->...` or other CodeIgniter
// methods in it. But we can't use them in
// `$this->request->setCallablePreConstructor()`
$mock = $this->testCase->getMockBuilder($classname);
$mockBuilder = $this->testCase->getMockBuilder($classname);
if ($constructor_params === false)
{
$mock->disableOriginalConstructor();
$mockBuilder->disableOriginalConstructor();
}
elseif (is_array($constructor_params))
{
$mock->setConstructorArgs($constructor_params);
$mockBuilder->setConstructorArgs($constructor_params);
}

$methods = [];
$onConsecutiveCalls = [];
$otherCalls = [];

foreach ($params as $key => $val) {
if (is_int($key)) {
$onConsecutiveCalls = array_merge($onConsecutiveCalls, $val);
$methods[] = array_keys($val)[0];
} else {
$otherCalls[$key] = $val;
$methods[] = $key;
}
}

$mock = $mockBuilder->setMethods($methods)->getMock();

foreach ($onConsecutiveCalls as $method => $returns) {
$mock->expects($this->testCase->any())->method($method)
->will(
call_user_func_array(
[$this->testCase, 'onConsecutiveCalls'],
$returns
)
);
}
$mock = $mock->setMethods($methods)->getMock();

foreach ($params as $method => $return)
foreach ($otherCalls as $method => $return)
{
if (is_object($return) && ($return instanceof PHPUnit_Framework_MockObject_Stub || $return instanceof PHPUnit\Framework\MockObject\Stub)) {
$mock->expects($this->testCase->any())->method($method)
Expand Down
32 changes: 28 additions & 4 deletions docs/FunctionAndClassReference.md
@@ -1,6 +1,7 @@
# ci-phpunit-test for CodeIgniter 3.x

version: **v0.18.0** |
version: **v0.19.0** |
[v0.18.0](https://github.com/kenjis/ci-phpunit-test/blob/v0.18.0/docs/FunctionAndClassReference.md) |
[v0.17.0](https://github.com/kenjis/ci-phpunit-test/blob/v0.17.0/docs/FunctionAndClassReference.md) |
[v0.16.1](https://github.com/kenjis/ci-phpunit-test/blob/v0.16.1/docs/FunctionAndClassReference.md) |
[v0.15.0](https://github.com/kenjis/ci-phpunit-test/blob/v0.15.0/docs/FunctionAndClassReference.md) |
Expand Down Expand Up @@ -407,6 +408,7 @@ $this->assertLogged('error', 'log message');
|---------------------|-------------|--------------------------------------------------------|
|`$classname` | string | class name |
|`$params` | array | [method_name => return_value] |
| | | [[method_name => [return_value1, return_value2 [, ...]]] |
|`$constructor_params`| false/array | false: disable constructor / array: constructor params |

`returns` (object) PHPUnit mock object
Expand Down Expand Up @@ -441,12 +443,34 @@ You can also set the mock itself as the return value of a mocked method with usi

~~~php
$mock = $this->getDouble('CI_Email', [
'to' => $this->returnSelf(),
'subject' => $this->returnSelf(),
'send' => TRUE,
'to' => $this->returnSelf(),
'subject' => $this->returnSelf(),
'send' => TRUE,
]);
~~~

You can create mocks with consecutive calls.

~~~php
$mock = $this->getMockBuilder('CI_Input')
->disableOriginalConstructor()
->setMethods(['method'])
->getMock();
$mock->expects($this->any())->method('method')
->will($this->onConsecutiveCalls('GET', 'POST' ,'DELETE'));
~~~

You could write code above like below:

~~~php
$mock = $this->getDouble(
'CI_Input',
[
['method' => ['GET', 'POST' ,'DELETE']],
]
);
~~~

**Upgrade Note for v0.10.0**

v0.10.0 has changed the default behavior of `$this->getDouble()` and disabled original constructor. If the change causes errors, update your test code like below:
Expand Down

0 comments on commit ac345dc

Please sign in to comment.