测试如何加倍,帮助我测试一个通过SoapClient与SOAP Web服务交互的单元

时间:2013-09-25 18:40:18

标签: php testing phpunit stub

我最近开始使用php进行测试。我很难理解如何测试外部服务以及存根将如何帮助我确保正在测试的方法确实像测试承诺一样。

以下示例是从代码中取得的,我无法理解如何测试。我只包含了有问题的构造和方法。

class SoapWrap {


        const WDSL_URL = 'http://traindata.dsb.dk/stationdeparture/Service.asmx?WSDL';

    /**
    *   The WDSL/SOAP Client
    *   @access private
    *   @var \SoapClient $Client
    */
    private $Client; // SOAP client.


    /**
    *   Sets up \SoapClient connection.
    *   @throws \SoapFault upon SOAP/WDSL error.
    */
    public function __construct( \SoapClient $SoapClient )
    {

        try 
        {

            $this->Client = $SoapClient;

        }
        catch( \SoapFault $SoapFault )
        {

            throw $SoapFault;
        }
    }


    /** 
    *   Gets all stations and filters if a filter is passed.
    *
    *   As DSB SOAP service only allows to get all stations 
    *   a filter can be used narrow down the results. 
    *   @param \DSBPHP\Filters\BaseFilter $StationFilte
    *   @return Array with station value objects.
    */
    public function getStations( \DSBPHP\Filters\FilterInterface $StationFilter = null )
    {
        // DSB soap service inforces only method for getting all stations...
        $stations = $this->Client->GetStations()->GetStationsResult->Station;

        if($StationFilter !== null) 
            return $StationFilter->run($stations);

        // return all trains
        return $stations;
    }
}

在下面的测试中,我试图确保测试不会使用SoapClient和SoapWrap,因为它使用SoapClient作为依赖。 SoapWrap double是因为 - > GetStations调用上面代码中getstations()内的soap服务。

class SoapWrapTest extends PHPUnit_Framework_TestCase {


    private $SoapWrap;


    public function setUp()
    {

        $SoapClient = $this ->getMockBuilder('\SoapClient')
                            ->setMethods(['__construct'])
                            ->disableOriginalConstructor()
                            ->getMock();

        $this->SoapWrap = $this ->getMockBuilder('\DSBPHP\App\SoapWrap')
                                ->setMethods(['__construct', 'getStations'])
                                ->disableOriginalConstructor()
                                ->setConstructorArgs([$SoapClient])
                                ->getMock();
    }


    public function testGetStationsReturnsArray()
    {

        $this->SoapWrap ->expects($this->once())
                        ->method('getStations')
                        ->will($this->returnValue([]));

        $stations = $this->SoapWrap->getStations();
        $this->assertInternalType('array', $stations);
    }
}

我不明白这是如何确保我真正的肥皂服务SoapWrap真正返回一个数组,以及我应该如何测试它。 据我所知,我的测试应该首先失败,直到我实现使其通过的代码。但是通过这个测试,其中最明显是错误的,它总是通过。这可以消除我从测试中可以理解的任何价值。

我希望你能帮助我一些如何真正测试这种方法的例子。

2 个答案:

答案 0 :(得分:2)

我不会100%理解您的问题中的示例,但如果我理解正确,您想要测试SoapWrap单元并且SoapClient作为协作者。

现在当你创建一个测试,如果SoapWrap::getStations()返回一个数组 - 它实际上总是这样 - 测试将始终通过。所以关于测试失败的第一个问题,直到它被实现(如在测试驱动开发(TDD)中:测试失败(红色);写入尽可能少的代码,直到它通过(黄色(或:绿色));重构代码(绿色(或:蓝色))),但你做错了。您必须在编写代码之前编写测试,例如第一次调用测试时,PHPunit会因为找不到SoapWrap类并且无法实例化的致命错误而崩溃,因为到目前为止还没有编写。

所以现在删除它并尝试忘记到目前为止你已完成的代码,重新运行测试以查看它失败然后再写新。

确保您之前已经对$StationFilter的课程进行了单元测试。

关于模仿的问题的第二部分:你嘲笑协作者,这里很可能是SoapClient::GetStations()方法。这将使您无需通过SOAP实际运行远程请求。这已经很容易了。你嘲笑合作者来测试单位。

答案 1 :(得分:0)

也许这可以帮助您试用您创建的Web服务,您可以尝试模拟使用此应用程序传输的数据。点击http://www.soapui.org/

感谢和安培;此致 Janitra Panji

相关问题