#php #unit-testing #mocking #phpunit #codeception
#php #модульное тестирование #издевательство #phpunit #codeception
Вопрос:
У меня есть класс следующим образом:
class Foo extends BaseObject {
public static function grab() {
// do some DB search and return an instance of self
// with the data in the object
return new Foo($id);
}
public function insert() {
// insert the data in the database for this object
return false;
}
public function delete() {
// delete the data from the database for this object
return false;
}
}
Как я могу издеваться над этим объектом, сохраняя при этом возможность утверждать, что вызовы insert
и delete
ведут себя так, как ожидалось?
Что я сделал, так это: use AspectMockTest;
$mock = Test::double('Foo', [
'grab' => Stub::make('Foo'),
'insert' => true,
'delete' => true,
]);
// ... later in the test ...
self::assertSame($foo->insert(), true);
$mock->verifyInvoked('insert', 1);
Это обходит макет для методов insert
and и update
возвращает false
вместо ожидаемого true
. Он также не учитывает вызовы, как ожидалось.
Итак, как я могу заставить макет вернуть себя?
(Пожалуйста, простите за любую путаницу между mock
и stub
, которую я, возможно, допустил)
Ответ №1:
Я предлагаю вам использовать Phake для моделирования статического метода, как описано здесь в документе, в качестве примера:
public function testInsert()
{
/** @var AppFoo $classUnderTest */
$classUnderTest = $this->getMockBuilder(Foo::class)
->disableOriginalConstructor()
->onlyMethods(['insert'])
->getMock();
$classUnderTest->expects($this->once())
->method('insert')
->willReturn(true);
/** @var AppFoo $fooGrab */
$fooGrab = Phake::mock(Foo::class);
Phake::whenStatic($fooGrab)
->grab()
->thenReturn($classUnderTest);
$mock = $fooGrab::grab();
$this->assertTrue($mock->insert());
}
Комментарии:
1. Я надеялся, что смогу сделать это без импорта другого целого пакета, просто чтобы пройти этот тест.
2. @Benjam Я понимаю, но PHPUnit не поддерживает статический макет и, похоже, Codeception тоже. В какой среде тестирования вы на самом деле участвуете в этом проекте?
3. AspectMock также доступен как часть этого пакета. Мы используем Codeception, который использует PHPUnit в качестве основы.