我不明白为什么在这次测试中会出现这个错误.我的测试似乎与代码的睡觉完全匹配.我忽略了什么?

In my test I have:

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

The error:

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

Part of my lack of understanding may have to do with the fact that I'm not sure what the Objects: array(....) is that appears at the bottom of the error.

推荐答案

TL;DR: your closure argument to Mockery::on needs to return true or false.

The longer explanation:

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

That was a rather confusing explanation, so I'll try an example :-)

Consider the following expectation:

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

如果被测系统(SUT)调用

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

and the value of $x will be "something".

现在,mockery的开发者意识到有一些他们根本无法满足的期望.例如(这是让我绊倒了一段时间的事情),一个闭合.事实证明,PHP中的闭包是一种复杂的内部资源,即使您以相同的方式定义两个闭包,它们也不会相同.请考虑:

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

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

将响应值"False".为什么?从我对这个主题的有限理解来看,它与PHP中闭包对象的内部表示有关.所以,当你模拟一个需要闭包作为参数的方法时,there is no way to satisfy the expectation.

Mockery::on()方法提供了一种解决方法.使用此方法,您可以向mockry传递一个(不同的)闭包,该闭包的计算结果为true或false,这取决于your个测试是否显示您有正确的参数.举个例子:

假设myclass::mymethod需要一个闭包作为参数.无论在SUT中传递给mymethod的闭包是什么,以下操作都将始终失败:

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

This is because Mockery will compare the argument passed in the SUT (a closure) to the closure defined above (function($v){ echo $v; }) and that test will fail, even if the two closures are identically defined.

使用Mockery::on(),您可以按如下方式重写测试:

$mock = Mockery::mock("myclass");
$mock->shouldReceive("mymethod")
    ->with(Mockery::on(function($value){
        return is_callable($value);
    }))
    ->once()
    ->andReturn("something");

Now when Mockery evaluates the expectation, it will call the closure passed as the argument to Mockery::on(). If it returns true, Mockery will consider the expectation passed; if it returns false, Mockery will consider it as having failed.

The expectation in this example will pass for any closure that is passed to myclass::mymethod, which is probably not specific enough. You probably want a more sophisticated test, but that's the basic idea.

Laravel相关问答推荐

Laravel:在行的子集上同步多对多

如何避免谷歌翻译翻译:参数

如何使用动态翻译键翻译 Laravel硬编码字符串(还有 1 个错误)..(验证异常类)

从主类别模型 laravel 中获取子类别翻译

处理程序类中的错误 - Laravel

使用 Eloquent (Laravel) 在 Group By 之前排序

laravel url 验证变音符号

Laravel 5.5 类型错误:传递给 Illuminate\Auth\EloquentUserProvider::validateCredentials() 的参数 1 必须是实例

在表单中添加一对多 - Backpack laravel

如何在 Laravel 5 中验证当前、新密码和新密码确认?

如何从不是控制器方法的方法发送响应?

干预图像:直接从带有原始文件名和分机的网址保存图像?

PHP Laravel:如何获取客户端浏览器/设备?

laravel 4:更新行时如何从列的当前值中减一?

Laravel 的 toSql() 方法是否会屏蔽 id? (列值被问号替换)

在 Laravel 测试用例中模拟一个 http 请求并解析路由参数

Laravel 事件、监听器、作业(job)、队列之间的区别

Laravel 中的 isDirty() 是什么意思?

Laravel 集合计数结果

如何在 Laravel 5.3 中获取当前的语言环境