Web Development
18-01-2024

Mocks and Stubs in php unit testing

Dmytro Tus
Full Stack Web developer

We use mocks when we want to test the class which has dependencies.

In out case InvoiceService is dependent from PaymentService;

Inside our PaymentService we have a pay method which makes an API request to some payment provider.

As we don't want to make real payment when we are testing our application we can create a "mock" of our service;

$this->createMock(PaymentService::class);

Then we need to return some specific data from our "pay" method.

And yes, we can do it and it called "stubbing"

$paymentServiceMock->method('pay')->wellReturn('data that we want to recieve from mock');

 

And here, for the understanding I will place whole code.

<?php

namespace Tests\Unit;

use Tests\TestCase;
use App\Services\InvoiceService;
use App\Services\PaymentService;

class InvoiceTest extends TestCase
{
    public function testInvoiceIsCreatedCorrectly(): void
    {
      $paymentServiceMock = $this->createMock(PaymentService::class);
      $paymentServiceMock->method('pay')->willReturn(['status' => 200, 'message' => 'payment is successful']);
      $invoiceService = new InvoiceService($paymentServiceMock);

      $customer = ['name' => 'Dmytro'];
      $amount = 1500;
      $result = $invoiceService->process($customer, $amount);
       
      $result->assertTrue($result);

    }

We can go deeper and also test our class that we are mocking.

Imagine that inside our PaymentService we have a method send which is executed inside 'pay' method. So with mocking in phpunit we can actually check is this method executed or not.

The code sample is here.

$paymentServiceMock->expects($this->once())
                                        ->method('send')
                                        ->with($customer);

With these knowelege we can test our code better.


Another posts