PHPUnit: How to mock a function on a class?

后端 未结 2 932
情书的邮戳
情书的邮戳 2021-01-17 04:33

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 sa

2条回答
  •  离开以前
    2021-01-17 04:59

    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:

    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
        }
    }
    

    Test:

    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));
        }
    }
    

提交回复
热议问题