11
votes

Comment se moquer de tester un service Web à PHPUnit sur plusieurs tests?

Je tente de tester une classe d'interface de service Web à l'aide de PHPUnit. Fondamentalement, cette classe appelle un objet SOAPCLIENT EM>. Je tente de tester cette classe dans PHPUnit en utilisant la méthode getmockfromwsdl code> décrite ici:

http://www.phpunit.de/manual/current/fr/test-doubles.html#test-doubles.stubbing -et-web-web-web-services p>

Cependant, étant donné que je veux tester plusieurs méthodes à partir de cette même classe, chaque fois que je configure l'objet, je dois également configurer le MOCK WSDL Objet de soapclient em>. Ceci provoque une erreur fatale d'être lancée: p> xxx pré>

Comment puis-je utiliser le même objet simulé sur plusieurs tests sans avoir à régénérer la WSDL à chaque fois? Cela semble être le problème. P>

- p>

Après avoir été invité à poster un code à examiner, voici la méthode de configuration dans la TESTCASE: P>

protected function setUp() {
    parent::setUp();

    $this->client = new Client();

    $this->SoapClient = $this->getMockFromWsdl(
        'service.wsdl'
    );

    $this->client->setClient($this->SoapClient);
}


0 commentaires

6 Réponses :


1
votes

Pour une utilisation de base, quelque chose comme ça fonctionnerait. Phpunit fait de la magie dans les coulisses. Si vous mettez en cache l'objet simulé, il ne sera pas redéclaré. Créez simplement une nouvelle copie à partir de cette instance mise en cache et vous devriez être bon à partir. XXX

Vous pouvez probablement cacher le nom de la classe avec get_class , puis créer un Nouvel instance, plutôt qu'une copie. Je ne sais pas combien de "magie" phpunit fait pour l'initialisation, mais cela vaut la peine d'être coupé. xxx


4 commentaires

J'ai posté du code dans la question pour examen. Le placement dans un class_existe ne semble pas que cela résoudrait le problème, car vous devez toujours récupérer l'objet simulé et que cette classe fonctionnera toujours cette évaluation. Sauf si je devais modifier phpunit lui-même? Qu'avez-vous pris en tête dans où placer la méthode CLASS_EXISTES ()?


Pas d'arrêt. Phpunit fait pas besoin de modification. Sérieusement. Pourquoi utilisez-vous EVAL? La classe qui exécute EVAL est le problème. Le chèque 'Class_Exists` est juste une suggestion de piratage pour empêcher la ré-déclaration d'une classe préexistante. Ce chèque doit être placé dans la classe effectuant "EVAL".


Phpunit appelle le code eval, pas mon propre code. Je pense que cela a quelque chose à voir avec quand il analyse le WSDL et crée des objets simulés de cette définition.


Cette méthode ne fonctionne pas bien. Une fois que vous appelez $ this-> Client-> getClient () -> s'attend ($ ceci-> n'importe quel ()) -> Méthode ('M Ethod') -> Ceci-€-> Volidvalue ( $ Résultat)); , tous les tests ultérieurs qui l'appelent également, mais avec un résultat différent ne renvoient que le premier résultat que celui-ci adopté. À une conjecture, le résultat est attaché au nom de la classe. Il doit donc être unique entre les appels.



1
votes

Pourquoi créez-vous la maquette dans la configuration () si le point est d'obtenir une définition de la classe moquée une fois par exécution d'un fichier de test complet? Si je me souviens bien, il est exécuté avant chaque test défini dans "cette" classe de test ... Essayez setupbeforeclass ()

de http://www.phpunit.de/manual/3.4/ EN / FIXTURES.HTML

En outre, les méthodes de modèle Setupbeforeclass () et TeReTownafterClass () sont appelées avant que le premier test de la classe de la casse est exécuté et après le dernier test de la classe de test de test, respectivement.


0 commentaires

-1
votes

phpunit crée une classe pour la simulation basée sur le WSDL. Le nom de classe, sinon fourni, est construit à partir du nom de fichier .WSDL, il est donc toujours pareil. À travers des tests, lorsqu'il essaie de créer à nouveau la classe, il se bloque.

La seule chose dont vous avez besoin est d'ajouter à la définition simulée Un nom de classe de classe, donc phpunit ne crée pas de nom automatique, remarquez le deuxième argument à $ this-> getmockfromwsdl: xxx

Vous pouvez maintenant créer autant de clients que vous le souhaitez, ne modifiez que le nom de classe pour chacun.


1 commentaires

Cela a le même problème, dans le deuxième test, il s'agira de «myMockClass» étant redéclamé.



4
votes

Ce n'est pas une solution idéale, mais dans votre configuration, donnez le savon simulé un nom de classe "aléatoire", par exemple xxx

ceci garantit qu'au moins lorsque la configuration est appelée. Ne pas obtenir cette erreur.


0 commentaires

0
votes

Ajout de ma 0,02 $ ici .. J'ai récemment couru sur cette même situation et après une frustration ici, c'est comment j'ai pu le résoudre: xxx

J'ai de nombreux "travailleurs", chacun dans leur propre classe de test et chacun a besoin d'accès à un objet SOAP moqué. Dans le deuxième paramètre à getmockfromwsdl Je devais m'assurer que je faisais un nom unique (par exemple, SOAPCLIENT_MYWORTERNER ) ou apporterait une collision PHPUnit.

Je ne sais pas si vous obtenez ou non le savon simulé à partir d'une fonction statique et d'avoir accès à la fonction getmockfromwsdl en passant dans $ CU comme paramètre est le meilleur moyen de accomplir cela, mais là y a-t-il.


0 commentaires

0
votes

Une façon de transmettre un objet du test à l'essai dans les phpunits est avec une dépendance des tests, si instanciation d'un objet particulier est trop taxable / temps prend beaucoup de temps:

<?php
/**
* Pass an object from test to test
*/
class WebSericeTest extends PHPUnit_Framework_TestCase
{

    protected function setUp() {
        parent::setUp();
        // I don't know enough about your test cases, and do not know
        // the implications of moving code out of your setup.
    }

    /**
    * First Test which creates the SoapClient mock object.
    */
    public function test1()
    {
        $this->client = new Client();

        $soapClient = $this->getMockFromWsdl(
            'service.wsdl'
        );

        $this->client->setClient($this->SoapClient);
        $this->markTestIncomplete();
        // To complete this test you could assert that the
        // soap client is set in the client object. Or
        // perform some other test of your choosing.

        return $soapClient;
    }

    /**
    * Second Test depends on web service mock object from the first test.
    * @depends test1
    */
    public function test1( $soapClient )
    {
        // you should now have the soap client returned from the first test.
        return $soapClient;
    }

    /**
    * Third Test depends on web service mock object from the first test.
    * @depends test1
    */
    public function test3( $soapClient )
    {
        // you should now have the soap client returned from the first test.
        return $soapClient;
    }
}
?>


0 commentaires