首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Phpunit - mocking SoapFault->getMessage()

Phpunit - mocking SoapFault->getMessage()
EN

Stack Overflow用户
提问于 2011-11-24 19:58:38
回答 3查看 2.5K关注 0票数 1

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

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

代码语言:javascript
复制
object(SoapFault)#7 (11) {
  ["message":protected]=>
  string(19) "{ 'INVALID_INPUT' }"

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

代码语言:javascript
复制
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()方法是最终的,所以我不能模拟它。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-11-25 20:49:50

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

SoapFault扩展了Exception,Exception期望输入($message,$code,$previous)。但是SoapFault期望($faultcode,$faultstring,$faultactor,$detail,$faultname,$headerfault)。这就是让我震惊的原因。

$faultstring映射到异常消息。

因此,为了嘲笑它,我做到了:

代码语言:javascript
复制
$mock_soap->expects($this->once())
                         ->method('checkVat')
                         ->will($this->throwException(new SoapFault('a', "Error Message")));

在我的实际代码中,$e->getMessage()现在返回'Error Message‘。

票数 1
EN

Stack Overflow用户

发布于 2011-11-24 21:09:39

应该没有必要嘲笑SoapFault。您可以只使用真正的异常(通常不会为测试而模拟异常,因为它们是)并模拟SoapClient来抛出准备好的异常。

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

因为我已经弄清楚了你的问题到底是什么,所以我构建了一个小的测试用例来确保它能工作。因为它已经在那里了,我猜代码比我能更好地解释它。

测试示例:

代码语言:javascript
复制
<?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";
            }   
        }   
    }   
}

输出:

代码语言:javascript
复制
 phpunit SoapFaultTest.php 
PHPUnit 3.6.3 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 3.75Mb

OK (1 test, 2 assertions)

断言保持简单,但您应该能够很容易地调整它以适应您处理错误的方式

票数 5
EN

Stack Overflow用户

发布于 2011-11-24 21:42:38

在edorian回答的旁边,应该不需要测试第三方组件是否如所宣布的那样工作。不要为你没有写过代码的组件写测试(或者你不能写代码的组件,如果它们坏了,它们就坏了,你就迷路了)。

只需测试您的代码是否按预期工作即可。你应该能够模拟你自己的代码。

例如:如果你的代码或数据丢失,你的代码总是会崩溃,例如,在某些情况下,你的应用程序的文件会被部分删除。你是否为这样的场景编写测试?当然不是。

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8256678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档