/FBMock

PHP Mocks Framework

Primary LanguagePHPApache License 2.0Apache-2.0

FBMock

FBMock is a PHP mocking framework designed to be simple and easy to use.

Unlike other mocking frameworks, FBMock is basically just stubs with spies. Instead of using a custom DSL and relying on opaque tear-down verification, FBMock encourages developers to program simple return behaviors and only use spies when appropriate.

Requirements

  • HHVM or PHP 5.4+

Note: the framework's tests use PHPUnit but PHPUnit is not necessary for using FBMock.

Usage

Include init.php which sets up the autoloader

require_once YOUR_FBMOCKS_DIR.'/init.php'

Install using Composer (optional)

To install this package via composer, just add the package to require and start using it.

{
    "require": {
        "facebook/fbmock": "*@dev"
    }
}

Creating a mock

mock('Foo')

Also, you can mock an interface in the same manner:

mock('IFoo')

Stubbing

By default, all methods return null. Helper methods for configuring return values are prefixed with 'mock'.

mock('Foo')->mockReturn('bar', 'return value here');

Sometimes, you need more control than mockReturn:

mock('Foo')->mockImplementation(
    'bar',
    function ($bar_type) {
        return $bar_type == 1;
    }
);

For other helpers (mockThrow, mockReturnThis, etc.) see Mock.php

Spying

$mock_foo = mock('Foo');
$mock->mockReturn('bar', 1);

$code_under_test->doSomething($mock_foo);

// Returns array of calls
$mock_foo->mockGetCalls('bar');

If you are using PHPUnit, you can add FBMock_AssertionHelpers to your base PHPUnit_TestCase to get some spying helpers:

$this->assertCalledOnce($mock_foo, 'bar');
$this->assertCalledOnce($mock_foo, 'bar', $expected_params_as_array); // param assertion is optional
$this->assertCalls($mock_foo, 'bar', $expected_params_for_first_call, $expected_params_for_second_call, ...);

Tips

Use multiset capabilities to improve legibility

mock('Foo')->mockReturn(array(
    'bar' => 1,
    'get' => 'data',
    'run' => true,
))->mockReturnThis('set', 'addID', 'removeID');

Utilize the fluent interface for concise mock setup.

mock('Foo')
    ->mockReturn('bar', 1)
    ->mockThrow('other_method')
    ->mockImplementation('another_method', function () { /* ... */ })
    ->mockReturnThis('setData');

Use strict mocks when it's critical a method isn't called

If any unmocked method is called, the mock will throw.

$db_conn = strict_mock('DBConnection')->mockReturn('read', $data);

// ...in code under test
$db_conn->write($some_data); // Throws FBMock_MockFrameworkException

Customizing

See CustomConfig-sample.php for instructions on customizing FBMock for your needs.

HHVM-only features

  • Mock final classes and classes with final methods
  • Mock internal classes

Community

We have a mailing list. If you're using FBMock, send us an email to say hi!