Mocka is clean, structured, but still very flexible mocking framework. It follows object-oriented guidelines to create mock classes, objects and their methods. Mocks can be modified during runtime before and once created or used. It has no assertion, expectations framework built-in - still fits well into any testing framework.
Mocka is registered as composer package on packagist.
"tomaszdurka/mocka": "dev-master"
Mocking classes
$parentClassName = 'Exception';
$class = new ClassMock('MockedException', $parentClassName);
$exception1 = $class->newInstance(['exception message as constructor argument']);
$exception2 = $class->newInstanceWithoutConstructor();
Creating object of mocked classes
$class = new ClassMock('MockedException', 'Exception');
$object = $class->newInstance('message');
$object->getMessage();
Mocking methods
$class = new ClassMock('MockedException', 'Exception');
$class->mockMethod('getMessage');
// It's also possible to mock method only for generated object
$object = $class->newInstance('message');
$object->mockMethod('getMessage');
// It's possible to mock non-existent methods - they will work once mocked
$class->mockMethod('foo');
// It's also possible to mock static methods
$class->mockStaticMethod('bar');
Modifying method behaviour
// Each method returned by any above mock methods return MethodMock object which can be manipulated
$class = new ClassMock('MockedException', 'Exception');
$mockedMethod = $class->mockMethod('getMessage');
// Set closure which will be executed when mocked method is called
$class->mockMethod('getMessage')->set(function () {
return 'modified message';
});
// Set numbered callbacks
$class->mockMethod('getMessage')
->set(function () {
return 'default message';
})
->at(0, function () {
return 'first message';
})
->at(2, function () {
return 'third message';
});
// There is also shortcut to make method return certain value
$class->mockMethod('getMessages')->set('default')->at(0, 'first message');
// To check how many times method has been called simply use mocked method object
$mockedMethod = $class->mockMethod('getMessage');
// call method...
echo $mockedMethod->getCallCount();
Mocking interfaces
$countableClass = new ClassMock('Collection', null, ['Countable']);
Referring back to original method
// It's a way to add extra behaviour to original method functionality
$class = new ClassMock('MockedException', 'Exception');
$object = $class->newInstanceWithoutConstructor();
$object->mockMethod('getMessage')->set(function() use ($object) {
return 'prefix-' . $object->callOriginalMethod('getMessage', func_get_args());
});
class TestCase extends \PHPUnit_Framework_TestCase {
use \Mocka\MockaTrait;
public function testFoo() {
// When using mocka trait there are two shortcut methods added to create mocked objects
$countableExceptionClass = $this->mockClass('DateTime', ['Countable']);
$dateTimeObject = $this->mockObject('DateTime', ['29-12-1984']);
}
public function testMockingMethod() {
$dateTimeObject = $this->mockObject('DateTime', ['29-12-1984']);
$this->assertSame('29', $dateTimeObject->format('d'));
$mockedFormatMethod = $dateTimeObject->mockMethod('format')->set('foo');
$this->assertSame(0, $mockedFormatMethod->getCallCount());
$this->assertSame('foo', $dateTimeObject->format('d'));
$this->assertSame(1, $mockedFormatMethod->getCallCount());
}
public function testMethodAssertions() {
$pdo = $this->mockClass('PDO')->newInstanceWithoutConstructor();
$pdo->mockMethod('exec')->set(function ($statement) {
$this->assertInstanceOf('PDOStatement', $statement);
});
}
}