Giter Site home page Giter Site logo

fbmock's Introduction

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!

fbmock's People

Contributors

carusogabriel avatar daniel15 avatar elynde avatar flarnie avatar rdohms avatar sch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fbmock's Issues

Mocking 'final' class fails but is not documented

<?php

require_once __DIR__.'/init.php';

final class C { }

mock('C');

Expected behavior: mock, or mention in documentation about this limitation.

Actual behavior: PHP Fatal error: Class FBMockFramework_C_FBMock__Mock_FBMock__MockObject may not inherit from final class (C) in /Users/epriestley/src/FBMock/TestDoubleCreator.php(33) : eval()'d code on line 2

Mocking nonexistent class produces meaningless error message

<?php

require_once __DIR__.'/init.php';

mock('C');

Expected behavior: not an internal Facebook error message.

Actual behavior: PHP Fatal error: Uncaught exception 'FBMock_TestDoubleException' with message 'Attempting to mock or fake I but I isn't loaded. Make sure you have the necessary require_module for it in the init file for your test (Tip: use cmf --fix flib/your_module/__tests/)' in /Users/epriestley/src/FBMock/TestDoubleCreator.php:12

Mocking does not work for namespaced classes

The test double creator doesn't seem to be able to create mocks for namespaced classes.

I've read before that at Facebook you don't use namespaces, so I understand this might be by design. However, as a lot of phpeople organise their classes using namespaces this would be a great feature to have incorporated to FBMock.

@elynde, you probably know if this is a hard thing to do or not within FBMock. What is your opinion on this?

Reproduction script:

<?php
namespace Test;

require_once 'vendor/facebook/fbmock/init.php';

class Foo {}

$creator = new \FBMock_TestDoubleCreator();
$testDouble = $creator->createTestDoubleFor('Test\Foo');

Result:

PHP Parse error:  syntax error, unexpected '\' (T_NS_SEPARATOR), expecting '{' in /path/to/file/vendor/facebook/fbmock/TestDoubleCreator.php(43) : eval()'d code on line 2
PHP Stack trace:
PHP   1. {main}() /path/to/file/bug.php:0
PHP   2. FBMock_TestDoubleCreator->createTestDoubleFor() /path/to/file/bug.php:13

Parse error: syntax error, unexpected '\' (T_NS_SEPARATOR), expecting '{' in /path/to/file/vendor/facebook/fbmock/TestDoubleCreator.php(43) : eval()'d code on line 2

Call Stack:
    0.0013     230088   1. {main}() /path/to/file/bug.php:0
    0.0043     418944   2. FBMock_TestDoubleCreator->createTestDoubleFor() /path/to/file/bug.php:13

PHP Fatal error:  Uncaught exception 'ReflectionException' with message 'Class FBMockFramework_Test\Foo__ does not exist' in /path/to/file/vendor/facebook/fbmock/TestDoubleCreator.php:46
Stack trace:
#0 /path/to/file/vendor/facebook/fbmock/TestDoubleCreator.php(46): ReflectionClass->__construct('FBMockFramework...')
#1 /path/to/file/bug.php(13): FBMock_TestDoubleCreator->createTestDoubleFor('Test\Foo')
#2 {main}
  thrown in /path/to/file/vendor/facebook/fbmock/TestDoubleCreator.php on line 46

Fatal error: Uncaught exception 'ReflectionException' with message 'Class FBMockFramework_Test\Foo__ does not exist' in /path/to/file/vendor/facebook/fbmock/TestDoubleCreator.php on line 46

ReflectionException: Class FBMockFramework_Test\Foo__ does not exist in /path/to/file/vendor/facebook/fbmock/TestDoubleCreator.php on line 46

Call Stack:
    0.0013     230088   1. {main}() /path/to/file/bug.php:0
    0.0043     418944   2. FBMock_TestDoubleCreator->createTestDoubleFor() /path/to/file/bug.php:13
    0.0057     469888   3. ReflectionClass->__construct() /path/to/file/vendor/facebook/fbmock/TestDoubleCreator.php:46

Doesn't work with PHP7 return type declarations

I tried to mock a class which have return type declared in it and got a fatal error:

FBMockFramework_AndreasGlaser__NS__PPC__NS__PPC_FBMock__Mock_FBMock__MockObject::getClient() must be compatible with AndreasGlaser\PPC\PPC::getClient()

From backtrace I can see that fbmock didn't prepare correct declaration for this method.

Mocking class with protected property $__mockImplementation fails

<?php

require_once __DIR__.'/init.php';

class C {
  protected $__mockImplementation;
}

mock('C');

Expected behavior: Mock

Actual behavior: PHP Fatal error: C and FBMock_MockObject define the same property ($__mockImplementation) in the composition of FBMockFramework_C_FBMock__Mock_FBMock__MockObject. However, the definition differs and is considered incompatible. Class was composed in /Users/epriestley/src/FBMock/TestDoubleCreator.php(33) : eval()'d code on line 5

composer

Why it's not available under composer and packagist?

FBMock might be not able to work with HHVM

Code example:

mockReturn('some_func', 2); $mocked_obj->some_func(); # Running the code by HHVM raises error: Fatal error: Syntax only allowed with -v Eval.EnableHipHopSyntax=true in FBMock/TestDoubleCreator.php(46) : eval()'d code on line 1 # The reason might be the code, which is to be eval()'d, begins with "<< __MockClass >>".

Mocking class which implements __wakeup() fatals

<?php

require_once __DIR__.'/init.php';

class C {
  public function __wakeup() { }
}

mock('C');

Expected behavior: Mock.

Actual behavior: PHP Fatal error: Call to a member function processMethodCall() on a non-object in /Users/epriestley/src/FBMock/TestDoubleCreator.php(36) : eval()'d code on line 5

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.