내 단위 테스트에서 메서드에 전달 된 Closure 함수가 정확히 한 번 호출되었는지 확인하려는 방법을 찾으려고합니다. . 하지만 PHP에서 Closure 클래스는 final로 선언되고이를 실행할 때 다음 오류 메시지가 나타납니다. "Class"Closure "가"final "로 선언되어 조롱을받을 수 없습니다."PHP 클로저가 함수에 매개 변수로 전달 된 것을 테스트하는 방법은 정확한 횟수로 호출되었습니다.
다음은 코드 예제입니다. valueProducer()가 정확히 한 번 호출되었는지 확인하려고합니다.
class PoorCache{
protected $storage;
/**
* Returns value from cache and if the value lacks puts it into the cache storage
* @param string $key
* @param Closure $valueProducer produces a value for storage, i.e. makes a request to DB
* @return mixed
*/
public function remember($key, Closure $valueProducer)
{
if (array_key_exists($key, $this->storage))
{
return $this->storage[$key];
}
$this->storage[$key] = $valueProducer();
return $this->storage[$key];
}
}
class PoorCacheTest extends TestCase {
public function testRemeber(){
$mockedValueProducer = $this->getMock(\Closure::class);
$mockedValueProducer->expects($this->once())->method('call');
$cache = new PoorCache();
$cache->remember('myKey', $mockedValueProducer);
$cache->remember('myKey', $mockedValueProducer);
}
}
[phpunit을 함께 폐쇄을 조롱에 대한 흥미로운 제안 (https://github.com/sebastianbergmann/phpunit-mock-objects/issues/257) –
나는 몰랐다' 클로저'는 흥미 롭다. 당신이 시도 할 수있는 한 가지 방법은'Closure' 타입 힌트를 제거하고 그 메소드의 시작 부분에'! is_callable()'과 같은 것을 기반으로하는 PHP 테스트를 추가하는 것입니다. 조롱 된 클래스가 호출 할 수있는 방법으로 놀아야 만합니다. (아마도 호출 마법을 구현하는 무언가의 일부가 아닌가? 여기에서 플레이해야 할 것입니다 ...) – halfer
답변 해 주셔서 감사합니다. 메소드 스펙에서 Closure를 제거하면 확실히 문제가 해결됩니다. 그러나 우회입니다. 나는 누군가가 솔직한 해결책을 알고 있는지 궁금해했다. – andrew