如何在类上模拟函数

如何在类上模拟函数

本文介绍了PHPUnit:如何在类上模拟函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个叫做"QueryService"的类.在此类上,有一个名为"GetErrorCode"的函数.在此类上,还包含一个称为"DoQuery"的函数.因此,您可以放心地说我有这样的事情:

I have a class called "QueryService". On this class, there is a function called "GetErrorCode". Also on this class is a function called "DoQuery". So you can safely say I have something like this:

class QueryService {
    function DoQuery($request) {
        $svc = new IntegratedService();
        $result = $svc->getResult($request);
        if ($result->success == false)
            $result->error = $this->GetErrorCode($result->errorCode);
    }

    function GetErrorCode($errorCode) {
         // do stuff
    }
}

我想创建一个将测试"DoQuery"的phpunit测试.但是,我希望通过模拟确定"GetErrorCode"的结果.换句话说,我想说的是,如果$ errorCode = 1,则GetErrorCode必须绕过此函数中的任何逻辑,并仅返回单词"ONE".如果它不是1,则必须返回"NO".

I want to create a phpunit test that will test "DoQuery". However, I want the result of "GetErrorCode" to be determined by a mock. In other words, I want to say that if $errorCode = 1, GetErrorCode must bypass whatever logic is in this function, and just return the word "ONE". If it is any number other than 1, it must return "NO".

如何使用PHPUNIT Mocks进行设置?

How do you set this up using PHPUNIT Mocks?

推荐答案

要测试此类,您可以模拟IntegratedService.然后,可以将IntegratedService::getResult()设置为返回您喜欢的模拟内容.

To test this class, you would mock the IntegratedService. Then, the IntegratedService::getResult() can be set to return what ever you like in a mock.

然后,测试变得更加容易.您还需要能够使用依赖注入来传递模拟的服务,而不是真实的服务.

Then testing becomes easier. You also need to be able to use Dependency Injection to pass the mocked service instead of the real one.

班级:

class QueryService {
    private $svc;

    // Constructor Injection, pass the IntegratedService object here
    public function __construct($Service = NULL)
    {
        if(! is_null($Service) )
        {
            if($Service instanceof IntegratedService)
            {
                $this->SetIntegratedService($Service);
            }
        }
    }

    function SetIntegratedService(IntegratedService $Service)
    {
        $this->svc = $Service
    }

    function DoQuery($request) {
        $svc    = $this->svc;
        $result = $svc->getResult($request);
        if ($result->success == false)
            $result->error = $this->GetErrorCode($result->errorCode);
    }

    function GetErrorCode($errorCode) {
         // do stuff
    }
}

测试:

class QueryServiceTest extends PHPUnit_Framework_TestCase
{
    // Simple test for GetErrorCode to work Properly
    public function testGetErrorCode()
    {
        $TestClass = new QueryService();
        $this->assertEquals('One', $TestClass->GetErrorCode(1));
        $this->assertEquals('Two', $TestClass->GetErrorCode(2));
    }

    // Could also use dataProvider to send different returnValues, and then check with Asserts.
    public function testDoQuery()
    {
        // Create a mock for the IntegratedService class,
        // only mock the getResult() method.
        $MockService = $this->getMock('IntegratedService', array('getResult'));

        // Set up the expectation for the getResult() method
        $MockService->expects($this->any())
                    ->method('getResult')
                    ->will($this->returnValue(1));

        // Create Test Object - Pass our Mock as the service
        $TestClass = new QueryService($MockService);
        // Or
        // $TestClass = new QueryService();
        // $TestClass->SetIntegratedServices($MockService);

        // Test DoQuery
        $QueryString = 'Some String since we did not specify it to the Mock';  // Could be checked with the Mock functions
        $this->assertEquals('One', $TestClass->DoQuery($QueryString));
    }
}

这篇关于PHPUnit:如何在类上模拟函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 19:01