php – 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']);
            })
        );

错误

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 (
    ),))

我缺乏理解的一部分可能与我不知道对象:数组(….)是否出现在错误底部的事实有关.

TL; DR:你的闭包参数Mockery :: on需要返回true或false.

更长的解释:

问题是你打电话给Mockery :: on.此方法一个闭包(或其他函数)作为参数.该关闭应该返回true或false,这取决于关闭的参数是否满足测试.

这是一个相当混乱的解释,所以我会尝试一个例子:-)

考虑以下期望:

$mock = Mockery::mock("myclass");
$mock->shouldReceive("mymethod")
    ->with("myargument")
    ->once()
    ->andReturn("something");

如果被测系统(SUT)调用,则会达到预期

$x = $myclass->mymethod("myargument");

并且$x的值将是“某事物”.

现在,Mockery的开发人员意识到有一些期望,他们根本无法满足.例如(这是一段让我失望的事情),一个关闭.事实证明,PHP中的一个关闭是一种复杂的内部资源,即使你定义了两个相同的闭包,它们也不一样.考虑:

$x = function($v){ echo $v; };
$y = function($v){ echo $v; };

echo $x==$y ? "True" : "False";

将回显“False”值.为什么?从我对这个主题的有限理解,它与PHP中的封闭对象的内部表示有关.所以,当你嘲笑一个需要关闭作为参数的方法时,没有办法满足期望.

Mockery :: on()方法提供了一个方法.使用这种方法,您可以将(不同的)闭包传递给评估为true或false的Mockery,这取决于您的测试是否显示您有正确的参数.一个例子:

想象一下,myclass :: mymethod需要一个闭包作为参数.以下将始终失败,无论您在SUT中传递给我的方法是什么封锁:

$mock = Mockery::mock("myclass");
$mock->shouldReceive("mymethod")
    ->with(function($v){ echo $v; })
    ->once()
    ->andReturn("something");

这是因为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");

现在当Mockery评估期望值时,它会调用作为参数传递给Mockery :: on()的闭包.如果返回真实,Mockery会考虑到期望通过;如果它返回false,Mockery会将其视为失败.

在这个例子中的期望将传递给传递给myclass :: mymethod的任何闭包,这可能不够具体.你可能想要一个更复杂的测试,但这是基本的想法.

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...