A few days ago I was explaining mocking to a few colleagues. I came up with the following quick n dirty code to show them the elegance of Mockery as a mocking framework.
The code is straight-forward: it checks the health of a server using a tiny heart beat script.
1. The script residing in the remote server:
1<?php
2
3$response = array('status' => 'online');
4
5header("Content-type: application/json");
6echo json_encode($response);
2. The class that tries to fetch the status from the remote server:
/test/Heartbeat.php
1<?php
2
3class Heartbeat
4{
5 private $http;
6
7 public function __construct(Http $http)
8 {
9 $this->http = $http;
10 }
11
12 public function checkHealth()
13 {
14 $url = 'http://localhost/remote/heart.php';
15 $response = $this->http->getResponse($url);
16
17 $beat = json_decode($response);
18 return (!is_null($beat) && $beat->status == 'online');
19 }
20}
3. The Http wrapper class that we will mock. Remember, in order to mock one object, we must be able to inject that object to the testing class using Dependency Injection.
/test/Http.php
1<?php
2class Http
3{
4 public function getResponse($url)
5 {
6 $response = @file_get_contents($url);
7 return $response;
8 }
9}
4. Finally, the test suite. Observe that we have mocked the Http class here using Mockery and have set expected function call and an expected result as per our need.
/test/HeartbeatTest.php
1<?php
2
3require_once 'gwc.autoloader.php';
4
5use Mockery as m;
6
7include_once 'Heartbeat.php';
8include_once 'Http.php';
9
10class HeartbeatTest extends PHPUnit_Framework_Testcase
11{
12 public function testSystemIsOnlineWhenServiceRuns()
13 {
14 $http = m::mock('Http');
15 $http->shouldReceive('getResponse')->andReturn('{"status":"online"}');
16
17 $heartbeat = new Heartbeat($http);
18 $response = $heartbeat->checkHealth();
19
20 $this->assertTrue($response);
21 }
22}
5. Make sure you have the following libraries installed (they have great install instructions):
6. Run the unit test using phpunit and it should pass:
1Emrans-MacBook-Air ~/Sites/test: phpunit HeartbeatTest.php
2
3PHPUnit 3.6.10 by Sebastian Bergmann.
4.
5
6Time: 0 seconds, Memory: 5.50Mb
7OK (1 test, 1 assertion)
7. Btw, the actual functionality is pretty simple to use as well. Check this script:
/test/check.php
1<?php
2
3include_once 'Heartbeat.php';
4include_once 'Http.php';
5
6$http = new Http();
7$heartbeat = new Heartbeat($http);
8$response = $heartbeat->checkHealth();
9
10echo ($response) ? 'Online' : 'Offline';
This is a very very simple use case and just meant to give an introduction. If you’re serious about unit testing, you should dig deeper into the concepts as well as into the PHPUnit and Mockery library documentations.