用嘲弄来嘲弄 trait 方法
Posted
技术标签:
【中文标题】用嘲弄来嘲弄 trait 方法【英文标题】:Mocking trait methods with mockery 【发布时间】:2017-09-01 16:57:43 【问题描述】:我有一个特点:
trait A
function foo()
...
还有一个使用这种特性的类:
class B
use A
foo as traitFoo;
function foo()
$intermediate = $this->traitFoo();
...
我想测试类的 foo()
方法并想模拟(使用 Mockery)特征的 foo()
方法的行为。我尝试使用部分和嘲笑traitFoo()
喜欢:
$mock = Mockery::mock(new B());
$mock->shouldReceive('traitFoo')->andReturn($intermediate);
但它不起作用。
可以这样做吗?有替代方法吗?我想测试 B::foo()
将其与 trait 的 foo()
实现隔离开来。
提前致谢。
【问题讨论】:
如何“它不起作用”。确切地?你在测试中称它为$mock->foo()
吗?一般来说,mock CUT 并不是很推荐。
是的,我将其称为$mock->foo()
。它不起作用,因为调用的是真正的特征方法而不是模拟方法。我使用模拟作为 CUT 的代理,并且能够在不依赖在其他地方测试的特征的情况下隔离方法测试。
【参考方案1】:
您使用的代理模拟来自模拟外部的代理调用,因此无法模拟 $this->...
类中的内部调用。
如果你没有 final 方法,你仍然可以使用普通的部分模拟或被动的部分模拟,它扩展了模拟类,并且没有这样的限制:
$mock = Mockery::mock(B::class)->makePartial();
$mock->shouldReceive('traitFoo')->andReturn($intermediate);
$mock->foo();
更新:
非模拟特征函数的完整示例:
use Mockery as m;
trait A
function foo()
return 'a';
function bar()
return 'd';
class B
use A
foo as traitFoo;
bar as traitBar;
function foo()
$intermediate = $this->traitFoo();
return "b$intermediate" . $this->traitBar();
class BTest extends \phpUnit_Framework_TestCase
public function testMe()
$mock = m::mock(B::class)->makePartial();
$mock->shouldReceive('traitFoo')->andReturn('c');
$this->assertEquals('bcd', $mock->foo());
【讨论】:
我试过这个,但其他对特征方法的调用停止工作。似乎模拟类不知道该特征的使用。 你需要更新问题。 “停止工作”是相当模糊的。请参阅我的更新以获取非模拟特征函数仍然有效的示例。 我找到了问题的根源。我的方法是受保护的,并且嘲讽说“不能被模拟,因为它是受保护的方法,并且这个模拟不允许模拟受保护的方法”。我卡住了吗? 我有点迷失在更新中。你能用一个重现问题的例子来编辑你的问题吗?如果只是保护traitFoo
,则需要在创建mock时加上->shouldAllowMockingProtectedMethods()
。
与->shouldAllowMockingProtectedMethods()
一起工作!谢谢!我在文档中的任何地方都找不到对此方法的引用...它没有记录吗?以上是关于用嘲弄来嘲弄 trait 方法的主要内容,如果未能解决你的问题,请参考以下文章