【问题标题】:Mock classes on unit tests with Codeception and Laravel 5 module使用 Codeception 和 Laravel 5 模块进行单元测试的模拟类
【发布时间】:2018-06-27 13:51:34
【问题描述】:
在单元测试中,这不起作用:
class SomeClassCest
{
public function tryToTest(UnitTester $I)
{
$mock = Mockery::mock(MyClass::class);
$mock->shouldReceive('action')->once()->andReturn(true);
$I->haveInstance(MyClass::class, $mock);
$classToTest = app(SomeClass::class);
// this method calls the MyClass action method
$classToTest->run();
// some asserts here
}
}
模拟没有生效,$mock->action 永远不会被调用,而是调用真正的实现。如何使用 Codeception 和 Laravel 5 模块模拟单元测试中的类?
【问题讨论】:
标签:
unit-testing
laravel-5
mocking
codeception
【解决方案1】:
通常,在单元测试中,amOnRoute、amOnPage 方法不会被调用,因此Laravel5->doRequest() 不会应用绑定,因此,为了模拟一个类,在 Codeception 套件的 Unit 助手中:
class Unit extends \Codeception\Module
{
/**
* @param $realClass
* @param $mock
*/
public function mockClass($realClass, $mock)
{
$this->getModule('Laravel5')->getApplication()->instance($realClass, $mock);
}
}
在单元测试中:
class SomeClassCest
{
public function tryToTest(UnitTester $I)
{
$mock = Mockery::mock(MyClass::class);
$mock->shouldReceive('action')->once()->andReturn(true);
$I->mockClass(MyClass::class, $mock);
$classToTest = app(SomeClass::class);
// this method calls the MyClass action method
$classToTest->run();
// the mocked classs is used insetad of the real one
// do some asserts here
}
}