Непроблемный контекст
Допустим, в Symfony 3.3 у нас есть контроллер по умолчанию, который пишет «Hello, world!»:
class DefaultController extends Controller
{
public function indexAction() : Response
{
return new Response( 'Hello, world!' );
}
}
Если я хочу его протестировать, я простосоздайте WebTestCase и сделайте некоторые утверждения на клиенте или сканере, например,
class DefaultControllerTest extends WebTestCase
{
public function testIndex()
{
$client = static::createClient();
$crawler = $client->request( 'GET', '/route/to/hello-world/' );
$this->assertEquals( 200, $client->getResponse()->getStatusCode() );
$this->assertContains( 'Hello', $crawler->filter( 'body' )->text() );
}
}
Это просто отлично работает.
Проблемный контекст
Допустим, у нас есть какой-то модульуслуги.Например, сервис IdGenerator
, который создает новые идентификаторы на основе определенного алгоритма, когда он нам нужен, и они представляют собой простой текст:
class IdGenerator
{
public function generateNewId() : string;
}
Скажем, мы внедряем его с помощью autowiring в контроллер.И мы ожидаем, что контроллер скажет что-то вроде Hello, world, on request 8bfcedbe1bf3aa44e0545375f0e52f6b969c50fb!
, откуда эта группа символов поступает из IdGenerator.
class DefaultController extends Controller
{
public function indexAction( IdGenerator $idGenerator ) : Response
{
$id = $idGenerator->generateNewId();
$message = sprintf( 'Hello, world, on request %s!', $id );
return new Response( $message );
}
}
Конечно, я мог бы перезагрузить страницу несколько раз в браузере и увидеть, как текст меняется со временемс новыми идентификаторами каждый раз.
Но это не тот случай, когда автоматизированные тесты должны появиться в мире.Мы должны посмеяться над IdGenerator, чтобы он возвращал определенный id
, чтобы утверждать:
class DefaultControllerTest extends WebTestCase
{
public function testIndex()
{
$id = 'test-id-test-id-test-id';
$idGenerator = $this->createMock( IdGenerator::class );
$idGenerator->method( 'generateNewId' )->willReturn( $id );
// What do I have to do with $idGenerator now here????
$client = static::createClient();
// Do something else here?
$crawler = $client->request( 'GET', '/admin/flights/search/' );
$this->assertEquals( 200, $client->getResponse()->getStatusCode() );
$this->assertContains( $id, $crawler->filter( 'body' )->text() );
}
}
Я уже проверял, чтобы получить контейнер из ядра, из клиента и установить там службу и ее не работает:
$id = 'test-id-test-id-test-id';
$idGenerator = $this->createMock( IdGenerator::class );
$idGenerator->method( 'generateNewId' )->willReturn( $id );
$client = static::createClient();
$kernel = $client->getKernel();
$container = $kernel->getContainer();
$container->set( 'My\Nice\Project\Namespace\IdGenerator', $idGenerator );
Он все еще получает автонастройку вместо той, которую я хочу (макет).
Вопрос
Какя могу настроить WebTestCase так, чтобы автоматическая проводка подключала мой поддельный сервис?