John Davidson

php - Test mocked service in controller in symfony 4.4

0 comments
Message:


I would like to test this controller on my symfony 4.4 project :


final class WebhookController extends AbstractController
{
private CustomLoggerService $customLogger;
private EntityManagerInterface $entityManager;
private MyService $myService;
private UserMailer $userMailer;
private AdminMailer $adminMailer;

public function __construct
(
CustomLoggerService $customLogger,
EntityManagerInterface $entityManager,
MyService $myService,
UserMailer $userMailer,
AdminMailer $adminMailer
)
{
$this->customLogger = $customLogger;
$this->myService = $myService;
$this->userMailer = $userMailer;
$this->adminMailer = $adminMailer;
$this->entityManager = $entityManager;
}

/**
* @Route("/webhook/new", name="webhook_new")
* @param Request $request
* @return Response
*/
public function new(Request $request)
{
$uri = $request->getUri();
$this->customLogger->info("new event uri ".$uri);
$query = $request->query->all();
if(isset($query['RessourceId']))
{
//infos
$id = $query['RessourceId'];
$event = $this->myService->getInfos($id);
$infoId = $event->infoId;
$this->customLogger->info("new info id ".$infoId);

$userRepo = $this->entityManager->getRepository(User::class);
$user = $userRepo->findOneByEventUserId((int)$event->owners[0]);

//mail sent
$this->userMailer->sendAdminEvent($event, $user);
$this->customLogger->info("new mail sent");

}
else
{
$this->adminMailer->sendSimpleMessageToAdmin("no ressource id", "no ressource id");
}
return new JsonResponse();
}
}

I need to mock MyService because it calls an external API


Here my test :


class WebhookControllerTest extends WebTestCase
{
use LoginTrait;

public function testNewPayinIRessourceIdExists()
{
self::ensureKernelShutdown();
/** @var KernelBrowser $client */
$client = $this->startClient();
$client->enableProfiler();

$myService = $this->createMock(MyService::class);
$myService->expects($this->once())->method("getInfos")->willReturn([
[
'hi'=>'hi'
]
]);


// if I do this, I can't inject my mocked service
$client->request('GET', '/webhook/new/?RessourceId=1111');

// if I do this, I can't autowire all my dependencies of my controller
$controller = new WebhookController(xxxx);
$controller->new(xxx);
}
}

What is the best way to test my controller ? If I do new WebhookController(xxxx) I have a lot of dependencies which need other dependencies and it's not maintenable.
Or I should move the customlog and sending emails in other service and keep the controller without these dependencies?



My Answer:
The best way to test your controller is to use Symfony's built-in testing tools and services. You can use the Symfony WebTestCase class to create functional tests for your controller.

In your test, you can mock the MyService class and inject it into the controller using Symfony's dependency injection container. This way, you can test the controller with all its dependencies without having to manually instantiate them.

Here's an example of how you can test your controller with mocked dependencies:

php
class WebhookControllerTest extends WebTestCase
{
use LoginTrait;

public function testNewPayinIRessourceIdExists()
{
$client = static::createClient();

$myService = $this->createMock(MyService::class);
$myService->expects($this->once())->method("getInfos")->willReturn([
[
'hi'=>'hi'
]
]);

$container = self::$container;
$container->set(MyService::class, $myService);

$client->request('GET', '/webhook/new/?RessourceId=1111');

// Assert your controller logic here
}
}


In this test, we create a mock of the MyService class and set it in the Symfony container using the set() method. This way, when the controller is instantiated, it will receive the mocked MyService instance as a dependency.

By using Symfony's testing tools and services, you can easily mock dependencies and test your controller in an isolated and maintainable way.

Rate this post

3 of 5 based on 5806 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us