user225269
user225269

Reputation: 10913

getting started with mocking in PHP

How do I get started with mocking a web service in PHP? I'm currently directly querying the web API's in my unit testing class but it takes too long. Someone told me that you should just mock the service. But how do I go about that? I'm currently using PHPUnit. What I have in mind is to simply save a static result (json or xml file) somewhere in the file system and write a class which reads from that file. Is that how mocking works? Can you point me out to resources which could help me with this. Is PHPUnit enough or do I need other tools? If PHPUnit is enough what part of PHPUnit do I need to check out? Thanks in advance!

Upvotes: 0

Views: 69

Answers (1)

Steven Scott
Steven Scott

Reputation: 11250

You would mock the web service and then test what is returned. The hard coded data you are expecting back is correct, you set the Mock to return it, so then additional methods of your class may continue to work with the results. You may need Dependency Injection as well to help with the testing.

class WebService {
    private $svc;

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

    function SetWebService(WebService $Service)
    {
        $this->svc = $Service
    }

    function DoWeb($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 WebServiceTest extends PHPUnit_Framework_TestCase
{
    // Simple test for GetErrorCode to work Properly
    public function testGetErrorCode()
    {
        $TestClass = new WebService();
        $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 testDoWebSericeCall()
    {
        // Create a mock for the WebService class,
        // only mock the getResult() method.
        $MockService = $this->getMock('WebService', array('getResult'));

        // Set up the expectation for the getResult() method 
        $MockService->expects($this->any())
                    ->method('getResult')
                    ->will($this->returnValue(1));      // Change returnValue to your hard coded results

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

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

This mock may then be used in the other functions since the return is hard coded, your normal code would process the results and perform what work the code should (Format for display, etc...). This could also then have tests written for it.

Upvotes: 1

Related Questions