Phpunit - 模拟SoapFault-> getMessage()

时间:2011-11-24 11:58:38

标签: php soap phpunit

我正在使用SOAP连接到third party service。此服务有时会返回SoapFaults。因为这是预期的,我想通过模拟SoapFaults来测试它。它将返回五种标准的SoapFault。

这是一个真正的SoapFault的开始:

object(SoapFault)#7 (11) {
  ["message":protected]=>
  string(19) "{ 'INVALID_INPUT' }"

我对此消息感兴趣。在我的代码中,我使用$ e-> getMessage()。

catch (SoapFault $e)
{
    // Catch any Soap faults and convert to an error message
    switch ($e->getMessage())
    {
        case "{ 'INVALID_INPUT' }":
            $this->addError(self::INVALID_INPUT);
            return FALSE;

但我无法弄清楚如何模拟SoapClient响应。 SoapClient对象似乎没有接受任何输入来设置消息,方法getMessage()是最终的,所以我无法模拟它。

任何想法都将不胜感激。感谢。

3 个答案:

答案 0 :(得分:5)

不应该模仿SoapFault。你可以使用真正的异常(通常不会因为Value objects而模拟测试异常)并模拟SoapClient来抛出你准备好的异常。

通过这样做,您无法模拟getMessage,因为您在测试用例中构建了SoapFault,如下所示。

因为我已经遇到了麻烦,想知道你究竟是什么问题,我建立了一个小测试案例,以确保它成功。因为它已经存在,我猜这段代码比我能解释得更好。

测试示例:

<?php

class SoapFaultTest extends PHPUnit_Framework_TestCase {

    public function testSoapFault() {
        $soapFault = new SoapFault("test", "myMessage");
        $soapClient = $this->getMockBuilder('SoapClient')
            ->setMethods(array('methodOnService'))
            ->disableOriginalConstructor()
            ->getMock();

        $soapClient->expects($this->once())
            ->method('methodOnService')
            ->will($this->throwException($soapFault));

        $x = new Consumer();
        $this->assertSame(
            "InvalidInput",
            $x->doSoapStuff($soapClient)
        );  
    }   

}

class Consumer {

    public function doSoapStuff(SoapClient $soapClient) {
        try {
            $soapClient->methodOnService();
        } catch(Exception $e) {
            if($e->getMessage() == "myMessage") {
                return "InvalidInput";
            }   
        }   
    }   
}

输出:

 phpunit SoapFaultTest.php 
PHPUnit 3.6.3 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 3.75Mb

OK (1 test, 2 assertions)

断言保持简单,但您应该能够轻松地根据您的错误处理方式进行调整

答案 1 :(得分:1)

除了edorian回答的内容之外,应该没有必要测试第三方组件是否像宣布的那样工作。不要为你没有编写代码的组件编写测试(或者你不能编写代码,如果它们被破坏,它们被破坏而你就丢失了)。

只是测试您的代码是否按预期工作。您应该可以模拟自己的代码。

示例:如果代码或数据丢失,您的代码将始终中断,例如应用程序的文件在某些​​情况下会被部分删除你是否为这种情况编写测试?自然不是。

但是,您可以自己编写一个集成套件,自动测试某些远程依赖项是否提供了预期的接口和响应。但我会把这个套件与你自己的代码库中的测试套件区分开来。

此外,您可以create your own assertion functions可以在每个测试用例中使用,例如,一个用于SoapClient异常消息。

答案 2 :(得分:1)

我要感谢hakre的评论。这正是我想要的。

SoapFault扩展了Exception,它需要输入($ message,$ code,$ previous)。 但SoapFault预计($ faultcode,$ faultstring,$ faultactor,$ detail,$ faultname,$ headerfault)。 这就是扔给我的。

$ faultstring映射到异常消息。

所以要嘲笑它,我做了:

$mock_soap->expects($this->once())
                         ->method('checkVat')
                         ->will($this->throwException(new SoapFault('a', "Error Message")));

在我的真实代码中 $ e-&gt; getMessage()现在返回'错误消息'