2

PHPUnit でテストしていますが、関数でテストが失敗します。しかし、理由はわかりません。モックしたい関数:

public function subscribe($email)
{
    $message = new SubscribeMessage();
    $message->setEmailaddress($email);
    $message->setLocale(Locale::getDefault());
    $this->getAmqpProducer()->publish($message, 'newsletter-subscribe');
    return true;
}

そして私の単体テスト:

public function testSubscribeSendsAmqpMessage()
{
    $email = 'email@email.nl';
    $locale = 'nl';

    $this->amqpProducerMock
        ->shouldReceive('publish')
        ->once()
        ->with(

            \Mockery::on(
                function ($message, $routingkey) use (&$publishedMessage) {
                    $publishedMessage = $message;
                    return $routingkey == 'newsletter-subscribe';
                }
            )
        );

    $this->service->subscribe($email, $locale);
}

しかし、テストは言う:

Mockery\Exception\NoMatchingExpectationException : No matching handler found for AcsiRabbitMq\Producer\Producer::publish(AcsiNewsletter\RabbitMq\Message\SubscribeMessage, "newsletter-subscribe"). Either the method was unexpected or its arguments matched no expected argument list for this method

単体テストを修正するにはどうすればよいですか? または、どうすればテストをリファクタリングできますか?

4

1 に答える 1

1

内部パブリッシュではなく、サブスクライブをモックします。テストを実行して ->subscribe を呼び出すと、クラス内のコードを実行しようとします。したがって、サブスクライブ()メソッドを実行しようとしますが、これはモックへの奇妙な参照を持っているようです。

通常、テストはサブスクライブをモックするため、ハードコーディングされたアサート テストの値を返すことができます。

通常のコードにある GetAmqpProducer() オブジェクトをモックしようとしたようです。使用するモック オブジェクトをクラスに渡すことができるか、それを割り当てることができる必要があります。

簡単な例:

class Email
{
    private $MsgObject;

    // Constructor Injection
    public __construct(SubscribeMessage $MessageObject)
    {
        $this->MsgObject = $MessageObject;
        ...
    }

    // Setter Injection
    public function SetSubscribeMessage(Subscribe $MessageObject)
    {
        $this->MsgObject = $MessageObject;
    }   

    public function setEmailaddress($email)
    {
        $this->MsgObject->emailAddress = $email;
        ...
    }

    public function setLocale($Locale)
    {
        $this->MsgObject->Locale = $Locale;
        ...
    }

    ...

}

上記のクラスのサンプルには、内部オブジェクトと依存関係が多すぎてテストできないため、テストでは実際にこれらが呼び出されるためです。依存性注入を使用して、オブジェクトを既知の状態で渡し、適切に返すようにします。

私は Mockery を使用していないため、Mockery でこれを行う方法を示していないことに注意してください。ただし、この簡単な例は、私が表現しようとしていることを理解するのに役立つはずです。

したがって、簡単なテストは次のようになります。

public function testSubscribeMessage()
{
    $email = 'email@email.nl';
    $this->Mock(
        ->shouldReceive('setEmailAddress')
        ->once()
        ->will_return($email)
        );

    $SubscribeMessage = new SubscribeMessage($this->Mock);
    $SetEmail = $SubscribeMessage->setEmailAddress($email);
    $this->assertEquals($email, $SetEmail);
}
于 2013-08-26T15:51:24.280 に答える