3 votes

PHPUnit passe un objet fantaisie comme argument au constructeur d'un autre objet et utilise la méthode expects().

J'essaie d'affirmer qu'une méthode sur un objet (objet testé) est appelée au moins une fois pendant la construction d'un autre objet. Je veux utiliser la fonction expects() de phpunit pour tester qu'une méthode getDetails() est appelée. Cette fonction est appelée pendant la construction d'un autre objet de compte client. Je dois manquer quelque chose de fondamental dans le fonctionnement de phpunit, mais j'aborde peut-être le problème avec un esprit python. Je sais que je pourrais faire fonctionner ceci en python mais peut-être que ce n'est pas possible ici ? Voici mon code de test :

public function testPhoneBookCode()
{
    $account = 'testaccount';

    $phone_book_mock = $this->getMockBuilder('\corp\data\PhoneBook')
        ->setConstructorArgs(array(null))
        ->setMethods(null)
        ->getMock();

    $expected = array(
        'id' => 1234,
        'title' => 'Mr',
        'first_name' => 'George',
        'last_name' => 'Smith',
        'phone' => '111-111-1111'
    );

    $phone_book_mock->expects($this->atLeastOnce())
        ->method('getDetails')
        ->with($this->equalTo(1234))
        ->will($this->returnValue($expected));

    try {
        $c = new Customer_Account(
            $account,
            true,
            'acme_corp',
            1234,
            null,
            null,
            $phone_book_mock
        );

    } catch ( \Exception $e ) {
        $this->fail("An unexpected exception has been raised [$account].". $e);
    }
}

À ce stade, je m'attends à ce que l'instanciation de la classe Customer_Account appelle la méthode getDetails de mon objet fantaisie et que la vérification atLeastOnce renvoie true.

Ce code est modifié à partir d'un exemple réel. Les fautes de frappe peuvent donc avoir été introduites lors de la re-saisie. Dans le code réel, le "phone_book" est passé dans le constructeur de l'objet Customer_Account et la méthode getDetails() est appelée dans ce constructeur. J'ai confirmé que la méthode est effectivement appelée et que j'obtiens la valeur de retour que j'attends. Cependant, mon test mock expects() échoue.

L'attente échouée pour le nom de la méthode est égale à lorsqu'elle est invoquée au moins une fois. L'invocation était attendue au moins une fois mais elle n'a jamais eu lieu.

L'objet fantaisie n'enregistre pas l'appel à getDetails() même si je suis sûr que le bon code est appelé. Est-ce que ce que j'essaie de faire n'est pas possible ? Est-ce que je perds la référence à l'objet fantaisie dès que je le passe à un autre constructeur ? Existe-t-il un autre moyen d'y parvenir ? Toute aide serait grandement appréciée.

0voto

localheinz Points 803

Cela devrait permettre d'affirmer que PhoneBook::details() est invoqué avec $id lorsque vous créez une instance de Customer_Account :

public function testPhoneBookCode()
{
    $id = 1234;

    $details = [
        'id' => $id,
        'title' => 'Mr',
        'first_name' => 'George',
        'last_name' => 'Smith',
        'phone' => '111-111-1111'
    ];

    $phoneBook = $this->createMock('corp\data\PhoneBook');

    $phoneBook
        ->expects($this->atLeastOnce())
        ->method('getDetails')
        ->with($this->identicalTo($id))
        ->willReturn($details);

    new Customer_Account(
        'testaccount',
        true,
        'acme_corp',
        $id,
        null,
        null,
        $phoneBook
    );
}

Pour référence, voir :

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