#symfony #testing #controller #symfony5
Вопрос:
Я пытаюсь издеваться над сервисом, чтобы протестировать один из методов моего контроллера:
class ExampleController extends AbstractController
{
/**
* @Route("/example", name="app_example", methods={"POST"})
*/
public function exampleMethod(Request $request, IService $service) {}
}
В тестовой среде я хотел бы подключить макет службы, но я не могу узнать, как вручную подключать аргументы контроллера (в отличие от аргументов службы). Это то, что я делал до сих пор, но это не работает:
//services_test.yaml
AppControllerExampleController:
arguments:
$service: '@AppServiceServiceMock'
Я получаю следующую ошибку:
Invalid service "AppControllerExampleController": class has no constructor.
Комментарии:
1.
arguments
директива предоставляет способ введения зависимости через конструктор, поэтому, если вы ее используете, вам нужно добавить конструктор, как указано @user9245255. Не могли бы вы добавить коды модульного теста, пожалуйста.2. Вы пытаетесь провести какой-то интеграционный тест? Если это так, то вы просто определите свою службу в тестовой среде. Код Symfony, который фактически вводит аргументы в методы действий, не является чем-то, что вы можете изменить. По крайней мере, нелегко.
Ответ №1:
Попробуйте добавить конструктор в свой контроллер и сделать IService его параметром
Комментарии:
1. Как именно добавление его в конструктор позволит внедрить другую реализацию в тестовую среду?
Ответ №2:
Ваш контроллер (src/Controller/ExampleController.php):
use AppServiceIService
class ExampleController extends AbstractController
{
/**
* @Route("/example", name="app_example", methods={"POST"})
*/
public function exampleMethod(Request $request, IService $service)
{
dd($service->testing());
}
}
Создайте свой пустой макет службы (src/Service/IService.php):
namespace AppService;
class IService
{
public function __construct()
{
}
public function testing(): string
{
return 'hello';
}
}
Symfony автоматически введет ваш сервис, вам не нужно добавлять его в свои сервисы.файл yaml. Однако не забудьте добавить use AppServiceIService
свой контроллер.
Комментарии:
1. Хммм. Вопрос в том, как внедрить другую реализацию IService в тестовую среду. В первую очередь не о том, как создать сервис.
2. @Cerad извините, тогда я неправильно понял вопрос. Это для модульного тестирования? Как бы вы это сделали?
3. Сам вопрос не очень ясен, но я думаю, что это интеграционный тест, и в этом случае вы бы определили тестовую реализацию IService в services_test. yaml, который переопределит реализацию по умолчанию. С другой стороны, в вопросе используется термин «макет», который обычно ассоциируется с модульным тестированием. Я думаю, нам просто нужно будет посмотреть, решит ли оригинальный плакат вернуться или нет.
4. Да, это интеграционный тест. Внедряемая служба полагается на внешние библиотеки и подключается к другим облачным сервисам, что замедляет тесты, а также заставляет меня проводить очень хрупкие тесты. Возможно, я неправильно использовал термин «макет», но, по сути, я хочу этого: предоставить поддельную реализацию, чтобы я проверял свою собственную логику, а не эту внешнюю службу.