因此,我试图为使用facade的代码编写一个单元测试,如下所示:
public function test() {
MYFACADE::doSomething();
}在单元测试中,我试图模拟正面调用:
MYFACADE::shouldReceive('doSomething')
->once()
->andReturn(false);唯一的问题是,当Laravel试图为MYFACADE创建一个底层类的实例时,它当然会运行构造函数,就在那里,是硬编码的数据库连接调用。因此,在不更改facade和从facade类的构造函数中删除数据库连接的情况下,是否可以在不运行facade构造函数的情况下模拟facade调用?
更新:设置的其余部分:
立面类
class MyFacade extends Facade
{
protected static function getFacadeAccessor()
{
return 'myfacade';
}
}app.php
$app->register(App\Providers\MyServiceProvider::class);
class_alias('App\Facades\MyFacade', 'MYFACADE');服务提供者:
class MyServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('myfacade', function()
{
return new myClasThatDoesSomething();
});
}
}facade使用的基础类。
class myClasThatDoesSomething
{
public function __construct()
{
// opens db connection here
}
public function doSomething()
{
}
}使用facade的示例类:
class TestClass
{
public function testMethod()
{
$returnValue = MYFACADE::doSomething();
return $returnValue;
}
}单元测试,检查testMethod()是否返回'testValue';
MYFACADE::shouldReceive('doSomething')
->once()
->andReturn('testValue');
$instance = new TestClass();
$value = $instance->testMethod();
$this->assertEquals('testValue', $value);发布于 2015-12-03 10:54:50
首先,Laravel文件读到:
外观为应用程序服务容器中可用的类提供了一个“静态”接口。
请确保您的MYFACADE遵循此模式。没有构造函数、数据库等的空间。如果您测试MYFACADE::doSomething(),您应该模拟该函数使用的所有其他类。
其次,下面的代码
MYFACADE::shouldReceive('doSomething')
->once()
->andReturn(false);模拟外观本身来测试使用 MYFACADE::doSomething()的其他东西。它应该返回Mockery的一个实例,只要在测试中调用MYFACADE::doSomething(),它就返回false。
编辑:
Laravel的Facade模拟实现实例化了底层类,它允许使用瘦构造函数测试服务。虽然这是最佳做法,但未必总能做到。假设不能将DB连接逻辑从构造函数中移出,最好的方法是手动模拟服务:
public function testTestMethod()
{
MYFACADE::swap(\Mockery::mock()
->shouldReceive('doSomething')
->once()
->andReturn('testValue')
->getMock()
);
$instance = new \App\TestClass();
$value = $instance->testMethod();
$this->assertEquals('testValue', $value);
}https://stackoverflow.com/questions/34063683
复制相似问题