我想测试非常具体的代码片段,但我找不到一个好方法。我有这样的代码:
public function testFoo()
{
$oauthException = new \OAuth2Exception('OAuth2Exception message');
//This is a $service Mock created with $this->getMockBuilder() in test case injected to AuthManager.
$this->service
->method('connectUser')
->will($this->throwException($oauthException));
//This is a $logger Mock created with $this->getMockBuilder() in test case injected to AuthManager.
$this->logger
->expects($this->once())
->method('error')
->with(
$this->isType('string'),
$this->logicalAnd(
$this->arrayHasKey('exception'),
$this->contains($oauthException)
)
);
//AuthManager is the class beeing tested.
$this->authManager->foo($this->token);
}
我想测试是否抛出异常并记录到$ this-> logger。但我无法找到一个好办法。我现在就是这样做的。
error
这将测试是否使用某些参数调用'exception'
方法,但数组键$this->logger->error(
$e->getMessage(),
[
'exception' => 'someValue',
'someKey' => $e,
]
);
和异常对象可以存在于数组的不同部分。我的意思是测试将通过这样的错误方法调用:
error
我想确保['exception' => $e]
方法始终会收到此类子集$this->logger
->expects($this->once())
->method('error')
->with(
$this->isType('string'),
$this->arrayHasSubset([
'exception' => $oauthException,
])
);
。这样的事情会很完美:
{{1}}
是否可以使用PHPUnit实现?
答案 0 :(得分:0)
您可以按照https://lyte.id.au/2014/03/01/spying-with-phpunit/
中的说明尝试PHPUnit间谍对于间谍,你可以做类似
的事情$this->logger->expects($spy = $this->any())->method('error');
$invocations = $spy->getInvocations();
/**
* Now $invocations[0]->parameters contains arguments of first invocation.
*/
答案 1 :(得分:0)
您可以使用callback()
约束:
public function testFoo()
{
$exception = new \OAuth2Exception('OAuth2Exception message');
$this->service
->expects($this->once())
->method('connectUser')
->willThrowException($exception);
$this->logger
->expects($this->once())
->method('error')
->with(
$this->identicalTo($exception->getMessage()),
$this->logicalAnd(
$this->isType('array'),
$this->callback(function (array $context) use ($exception) {
$expected = [
'exception' => $exception,
];
$this->assertArraySubset($expected, $context);
return true;
})
)
);
$this->authManager->foo($this->token);
}
请参阅https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.mock-objects:
callback()
约束可用于更复杂的参数验证。此约束将PHP回调作为其唯一参数。 PHP回调将接收要验证的参数作为其唯一参数,如果参数通过验证则返回true,否则返回false。
另请注意我如何调整设置您的测试双打:
connectUser()
只能被调用一次$this->willThrowException()
代替$this->will($this->throwException())
$this->identicalTo($exception->getMessage())
代替更宽松的$this->isType('string')
我总是试图让论证尽可能具体,只是放松对意图的约束。