myo*_*yol 15 php testing integration-testing laravel
我们有一些传统的laravel项目,它们在课堂上使用外墙.
use Cache;
LegacyClass
{
public function cacheFunctionOne()
{
$result = Cache::someFunction('parameter');
// logic to manipulate result
return $result;
}
public function cacheFunctionTwo()
{
$result = Cache::someFunction('parameter');
// different logic to manipulate result
return $result;
}
}
Run Code Online (Sandbox Code Playgroud)
我们最近的项目使用依赖注入外墙所代表的层级类,正如Taylor Otwell本人所暗示的那样.(我们对每个类使用构造函数注入,但为了保持示例简短,这里我使用方法注入并使用单个类.)
use Illuminate\Cache\Repository as Cache;
ModernClass
{
public function cacheFunctionOne(Cache $cache)
{
$result = $cache->someFunction('parameter');
// logic to manipulate result
return $result;
}
public function cacheFunctionTwo(Cache $cache)
{
$result = $cache->someFunction('parameter');
// different logic to manipulate result
return $result;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道外墙可以被嘲笑
public function testExample()
{
Cache::shouldReceive('get')
->once()
->with('key')
->andReturn('value');
$this->visit('/users')->see('value');
}
Run Code Online (Sandbox Code Playgroud)
这适用于单元测试.我试图理解的问题是,这些外墙是否被"全球性"嘲弄.
例如,让我们想象一下我写的集成测试(测试一些相互关联的类别而嘲讽的服务-而不是目的使用Live服务结束测试),这在某些时候,执行两个独立的类包含调用同样的方法相同门面具有相同的参数.
在这些被调用的类之间,有一些复杂的功能可以使用相同的参数更改该Facade方法返回的数据.*
$modernClass->cacheFunctionOne($cache); // easily mocked
// logic that changes data returned by laravel Cache object function 'someFunction'
$modernClass->cacheFunctionTwo($cache); // easily mocked with a different mock
Run Code Online (Sandbox Code Playgroud)
我们的现代类很容易测试,因为facade表示的底层类被注入到每个类中(在本例中,每个方法).这意味着我可以创建两个单独的模拟并将它们注入每个类(方法)以模拟不同的结果.
$legacyClass->cacheFunctionOne();
// logic that changes data returned by laravel Cache object function 'someFunction'
$legacyClass->cacheFunctionTwo();
Run Code Online (Sandbox Code Playgroud)
但是在遗留系统中,似乎模拟的外观是"全局的",因此当在每个类中运行外观时,将返回完全相同的值.
我在想这个是正确的吗?
*我理解这个例子从代码架构和测试的角度来看似乎完全是多余的,但我正在剥离所有真正的功能,尝试给出一些我所要求的"简单"示例.
依赖注入与外观
依赖注入的一个主要好处是,一旦开始将依赖项注入方法而不是在方法中实例化/硬编码它们,代码就会变得更加可测试.这是因为您可以从单元测试内部传入依赖项,它们将通过代码传播.
请参阅:http://slashnode.com/dependency-injection/
依赖注入与Facades形成鲜明对比.Facade是静态全局类,PHP语言不允许在静态类上覆盖或替换静态函数.Laravel外墙使用Mockery提供模拟功能,并且它们受到与上述相同的事实的限制.
集成测试的问题可能出现在您希望从非模拟缓存中检索数据的地方,但是一旦您使用Facade :: shouldReceive(),那么Facade :: get()将被模拟的Cache覆盖.反之亦然.因此,Facades不适用于交换模拟和未模拟数据的调用.
为了使用您需要的不同数据集测试代码,最佳做法是重构遗留代码以使用DI.
集成测试
方法更简单
另一种方法是在集成测试开始时调用多个Facade :: shouldReceive().确保您在集成测试中为每个呼叫以正确的顺序获得正确数量的期望.考虑到现有的代码库,这可能是编写测试的更快捷方式.
更难的方法
虽然依赖注入是编程最佳实践.很可能你的代码库有这么多遗留类,重构需要不可思议的时间.在这种情况下,考虑使用带有夹具的测试数据库进行端到端集成测试可能是值得的.
附录:
fhinkel commented on Feb 6, 2015:https://github.com/padraic/mockery/issues/401| 归档时间: |
|
| 查看次数: |
1014 次 |
| 最近记录: |