Tests unitaires (PHPUnit)


#1

Bonjour,
Je suis un peu perdu dans le fonctionnement des tests unitaires et surtout son implementation en PHP . D’après ce que j’ai pu comprendre, l’idée est d’effectuer des tests sur des composants d’une application (des objects, classes ou fonctions ). Ces tests dovent permettre de déterminer si un composant se comporte comme il se doit.

J’ai commencé à lire un peu PHPUnit https://phpunit.readthedocs.io/fr/latest/ pour comprendre mais je crois que je suis encore loin du compte.

J’ai une application php fait avec Slim et Illuminate Eloquent. J’ai un controlleur que j’aimerai bien tester si ca comporte comme je l’attend mais je suis un peu perdu.

Pour essayer, je veux tester le code ci-dessous :

<?php
class PostController
{
    /**
     * Liste des articles avec la possibilité de trier ou de filtrer par abonnement
     * 
     * @param Request $request
     * @param Response $response
     * @param array $params
     * @return Response
     */
    public function index(Request $request, Response $response, $params = [])
    {
        return false;

        try {
            $user = User::find($request->getAttribute('uid'));
    
            $posts = $user->posts();

            $sort = [
                'order' => $request->getQueryParam('order', 'desc'),
                'field' => $request->getQueryParam('sort', 'published_at')
            ];
    
            $posts->orderBy($sort['field'], $sort['order']);
            $posts->with('feed')->simplePaginate(10, ['*'], 'page', (int) $request->getQueryParam('page', 1));
    
            return $response->withJson($posts);
        } catch (\Exception $e) {
            return $response->withJson($e->getMessage())->withStatus(500);
        }
    }

}

Avec

<?php
use PHPUnit\Framework\TestCase;
use \Pi\Controller\PostController;
use \Slim\Http\Response;
use \Slim\Http\Request;

class PostControllerTest extends TestCase
{
    public function testGetPosts()
    {
        $response = $this->createMock(Response::class);
        $request = $this->createMock(Request::class);
        
        $stub = $this->createMock(PostController::class);

        $stub->method('index')->willReturn($response);

        $this->assertSame($response, $stub->index($request, $response, array()));
    }
}


Déjà avec ca, ca devrait retourner une erreur sauf que non. Les tests sont OK.


#2

Hello. Déjà, tu ne pars pas sur le cas d’utilisation le plus simple : tu fais du test unitaire et du mock.

Ici en gros, tu fais un mock (une doublure) de ton controller, tu lui dit qu’il doit renvoyer $response lorsque tu appelles la méthode index, peu importe ses arguments.

Forcément, dans ton assertSame, tu vas trouver que la méthode index de ta doublure va effectivement renvoyer $response. C’est ce que tu lui as demandé explicitement de faire.

Conseil : si tu débutes dans le domaine des test u, commence par des tests simples qui ne nécessitent pas d’utiliser des mocks, genre sur des fonctions qui ne font pas appel aux fonctionnalités du framework, ni à l’ORM.

Une fois que c’est bien maîtrisé, tu peux éventuellement ajouter des mocks. Toutefois, il faut voir que les mocks touchent un domaine à part : plutôt que de tester des règles métier, tu vas tester des interactions entre tes objets.