Web*_*net 12 php laravel mockery
我无法弄清楚为什么我在这次测试中遇到这个错误.我的测试似乎与其余代码完全匹配.我在俯瞰什么?
在我的测试中,我有:
$passwordBroker = m::mock('Illuminate\Auth\Reminders\PasswordBroker');
$passwordBroker->shouldReceive('reset')
->once()
->with(
$this->resetAttributes,
m::on(function (\Closure $closure) {
$this->entity
->shouldReceive('setAttribute')
->once()
->with('password', $this->resetAttributes['password']);
$this->entity
->shouldReceive('getAttributes')
->once()
->andReturn($this->resetAttributes);
$closure($this->entity, $this->resetAttributes['password']);
})
);
Run Code Online (Sandbox Code Playgroud)
错误:
Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_4_Illuminate_Auth_Reminders_PasswordBroker::reset(array('email'=>'test@email.com','password'=>'myTestPassword','password_confirmation'=>'myTestPassword',), Closure). Either the method was unexpected or its arguments matched no expected argument list for this method
Objects: (array (
'Closure' =>
array (
'class' => 'Closure',
'properties' =>
array (
),
'getters' =>
array (
),
),
))
Run Code Online (Sandbox Code Playgroud)
我缺乏理解的部分原因可能与我不确定Objects: array(....)错误底部出现的事实有关.
Kry*_*ten 41
TL; DR:Mockery::on需要返回的闭包参数true或false.
更长的解释:
问题出在你的电话上Mockery::on.此方法将闭包(或其他函数)作为参数.该闭包应返回true或false,具体取决于闭包的参数是否满足测试.
这是一个相当混乱的解释,所以我会尝试一个例子:-)
考虑以下期望:
$mock = Mockery::mock("myclass");
$mock->shouldReceive("mymethod")
->with("myargument")
->once()
->andReturn("something");
Run Code Online (Sandbox Code Playgroud)
如果被测系统(SUT)调用,则将满足此期望
$x = $myclass->mymethod("myargument");
Run Code Online (Sandbox Code Playgroud)
而价值$x将是"某事".
现在,Mockery的开发人员意识到他们根本无法满足一些期望.例如(这是让我绊倒一段时间的东西),一个闭包.事实证明,PHP中的闭包是某种复杂的内部资源,即使您以相同的方式定义两个闭包,它们也不会相同.考虑:
$x = function($v){ echo $v; };
$y = function($v){ echo $v; };
echo $x==$y ? "True" : "False";
Run Code Online (Sandbox Code Playgroud)
将回显价值"假".为什么?从我对该主题的有限理解来看,它与PHP中闭包对象的内部表示有关.所以,当你在模拟一个需要闭包作为参数的方法时,没有办法满足期望.
该Mockery::on()方法提供了一种方法.使用此方法,您可以将(不同的)闭包传递给Mockery,该闭包的结果为true或false,具体取决于您的测试是否显示您具有正确的参数.一个例子:
想象一下,myclass::mymethod需要一个闭包作为参数.无论您mymethod在SUT中传递什么闭包,以下内容总是会失败:
$mock = Mockery::mock("myclass");
$mock->shouldReceive("mymethod")
->with(function($v){ echo $v; })
->once()
->andReturn("something");
Run Code Online (Sandbox Code Playgroud)
这是因为Mockery会将SUT(闭包)中传递的参数与上面定义的闭包(function($v){ echo $v; })进行比较,即使两个闭包的定义相同,测试也会失败.
使用Mockery::on(),您可以按如下方式重写测试:
$mock = Mockery::mock("myclass");
$mock->shouldReceive("mymethod")
->with(Mockery::on(function($value){
return is_callable($value);
})
->once()
->andReturn("something");
Run Code Online (Sandbox Code Playgroud)
现在,当Mockery评估期望时,它将调用作为参数传递的闭包Mockery::on().如果它返回true,Mockery将考虑期望通过; 如果它返回false,Mockery会认为它失败了.
此示例中的期望将传递给传递给的任何闭包myclass::mymethod,这可能不够具体.您可能想要更复杂的测试,但这是基本的想法.
如果您像我一样不明白为什么它会抛出错误,那么当您有多个函数参数时,您需要替换->with()为, 。->withArgs()
$mock->shouldReceive('functionWithMoreParams')->withArgs(fn($arg1, $arg2) => true);
Run Code Online (Sandbox Code Playgroud)
$mock->shouldReceive('functionWithMoreParams')->with(fn($$arg1, $arg2) => true);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8819 次 |
| 最近记录: |