2 votes

Tests unitaires en PHP : Comment tester les fonctions de bas niveau d'une API externe ?

Bonjour les gens, J'ai écrit une implémentation de bas niveau pour une XmlRPC-Api et j'ai du mal à tester la communication.

Voici mon code.

abstract class BaseClient
{
    protected function call($method, array $params = array())
    {
        $request = xmlrpc_encode_request($method, $parameters);

        $file = file_get_contents($this->getDSN(), false, $context);
        $response = xmlrpc_decode($file);

        if ($response && xmlrpc_is_fault(array($response))) {
            trigger_error("xmlrpc: {$response[faultString]} ({$response[faultCode]})");
        }

        return $response;
    }
}

Client extends BaseClient
{
    public function testCall($msg)
    {
        return $this->call('testMethid', array($msg));
    }
}

Et voici mon test.

ClientTest extends PHPUnit_FrameWork_TestCase
{
    public function testTestCall()
    {
        $c = new Client();
        $resp = $c->testCall('Hello World');

        $this->assertEquals('Hello World', $resp);
    }
}

Ce test se plante à chaque fois, car il n'est pas possible d'accéder à l'api à l'intérieur d'un environnement de test. Je ne vois pas de solution pour simuler et injecter l'api call fonction. Que puis-je faire ? Peut-être que ma structure d'objet est mauvaise et ne permet pas de tester et comment puis-je améliorer cette structure (si cela se produit) ?

Santé.

2voto

Marty Penner Points 188

Puisque vous essayez de tester une API externe, je commencerais par envelopper votre file_get_contents() dans une autre classe et l'injecter dans votre BaseClient. Dans sa forme la plus simple, cela peut ressembler à quelque chose comme ceci :

class RemoteFileRetriever
{
    public function retrieveFileContents($url)
    {
        // Do some work to create $context
        ...

        // Now grab the file contents
        $contents = file_get_contents($url, false, $context);

        return $contents;
    }
}

abstract class BaseClient
{
    private $fileRetriever;

    public function __construct(RemoteFileRetriever $fileRetriever)
    {
        $this->fileRetriever = $fileRetriever;
    }

    protected function call($method, array $params = array())
    {
        ...

        $file = $this->fileRetriever->retrieveFileContents($this->getDSN());

        ...
    }
}

Maintenant, dans votre test, vous pouvez utiliser un objet fictif à injecter en tant que récupérateur de fichiers. Par exemple :

class ClientTest extends PHPUnit_FrameWork_TestCase
{
    public function testTestCall()
    {
        $mockRetriever = new MockRemoteFileRetriever();
        $c = new Client($mockRetriever);
        $resp = $c->testCall('Hello World');

        $this->assertEquals('Hello World', $resp);
    }
}

PHPUnit dispose de quelques aides intégrées pour le mocking. Voir Objets fictifs de PHPUnit .

0voto

Schleis Points 9098

Vous ne voulez pas vous moquer de la call fonction.

Si vous ne pouvez pas mettre en place un faux service, vous devez simuler les fonctions PHP, ce que vous pouvez faire en utilisant PHP Namespacing (vous devez avoir PHP 5.3). Vous pouvez alors créer des mocks pour les fonctions php internes que vous appelez dans votre méthode d'appel.

http://www.schmengler-se.de/-php-mocking-built-in-functions-like-time-in-unit-tests

Si vous n'êtes pas en mesure de le faire, les tests peuvent s'avérer très difficiles. Pouvez-vous créer une fausse interface utilisateur que vous pouvez utiliser pour les tests ? Rappelez-vous que vous ne testez pas les méthodes de l'API, mais que vous essayez de vous assurer que votre code fait la demande à l'API et traite la réponse de la manière que vous souhaitez.

En règle générale, il faut partir du principe que le code d'un tiers a été testé et qu'il fonctionne correctement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X