I'm working with FOSRestBundle and Symfony4 to create a REST API, and I overwrote the default view to always return an object as following:
{
code: 200,
message: 'Success!',
data: {}
}
For exceptions, the code and the message will change to 404, 401, 403, and so on.
To achieve that, I created my own view classes that extends \FOS\RestBundle\View\View, so now I can return my view object in any controller action, and since I have the view_response_listener enabled on fos_rest.yaml, the FOSRestBundle will listen to my View return and transform it into a Response. For example:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use App\View\Ok;
use App\Entity\User;
/**
* @Rest\Route("/user")
*/
class UserController extends FOSRestController
{
/**
* @Rest\Get("/")
*/
public function getUserAction(Request $request)
{
$users = $this->getDoctrine()
->getRepository(User::class)->findAll();
return new Ok(['users' => $users]);
}
}
So in this example, the API output should be:
{
code: 200,
message: 'Success!',
data: { users: [ /* Users here... */ ] }
}
Ok, so far so good. The problem is that I need to test if given a request sent to a fake controller, that has actions to simulate success and exception return, I get the properly object, using my View.
I'm using Behat, so I'm going to write this example scenario:
Scenario: "Ok" response test
When send a request to "/response-test/ok"
Then the response status code should be 200
And the response should to be JSON
And the response should to be equal
"""
{
code: 200,
message: 'Success!',
data: {}
}
"""
Scenario: "Not found" response test
When send a request to "/response-test/not-found"
Then the response status code should be 404
And the response should to be JSON
And the response should to be equal
"""
{
code: 404,
message: 'Not found!',
data: {}
}
"""
My question is: is there a way to define a fake controller, as following, that act exactly like a real controller (including the annotations and REST behavior), but that lives in my test suite, and servers only to my tests? Something like:
<?php
namespace App\Tests;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use App\View\Ok;
use App\View\NotFound;
/**
* @Rest\Get("/response-test")
*/
class TestController extends FOSRestController
{
/**
* @Rest\Get("/ok")
*/
public function okAction(Request $request)
{
return new Ok();
}
/**
* @Rest\Get("/not-found")
*/
public function notFoundAction(Request $request)
{
return new NotFound();
}
}
I can't make this controller work because when I define it outside the folder src/Controller, Symfony doesn't recognize it, and I don't want to define this controller together the application's one.
What is the best way to make this test?
Aucun commentaire:
Enregistrer un commentaire