php - Laravel 4 中的模拟回调(Mockery)

标签 php unit-testing laravel-4 mockery

我目前正在为 Laravel 4 中的一个包编写测试。

我在模拟 Illuminate\Database\Query\Builder 它几乎一直工作,除非 where 方法使用回调,我无法检查内部方法是否调用回调。

我希望你们中的任何一个人能给出一些启示。

$query = \Mockery::mock('Illuminate\Database\Query\Builder', function ($mock) {
    /** @var \Mockery\Mock $mock */
    $mock->shouldReceive('where');
    $mock->shouldReceive('orWhere')->twice();
});

以及应调用orWhere 的实际where 方法。 注意:该构建器模拟将传递给下面的类。

$builder = new LaravelBuilder($query);

然后调用包含以下代码的 $builder->filter()

$this->query->where(function ($query) use ($filterData) {
    /** @var \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query */
    foreach($filterData['columns'] as $colData) {
        /** @var \Samvaughton\Ldt\Column $column */
        $column = $colData['column'];

        // See if this column is searchable
        if (!$column->isSearchable() || !$colData['searchable']) continue;

        // If the individual column term is empty, use the main term
        $term = (empty($colData['term'])) ? $filterData['term'] : $colData['term'];

        // Actually apply the filter
        $query->orWhere($column->getSqlColumn(), "LIKE", "%{$term}%");
    }
});

主要部分是底部位 $query->orWhere,PHPUnit 测试每次都失败,因为它甚至没有运行一次 orWhere。在您说它可能由于 continue 而无法执行之前,我传递的数据将允许这样做。

我怀疑这是因为我首先是如何模拟 where 方法的。如果我在 foreach 之前包含一个 exit,它不会执行,这表明它甚至没有在回调中运行任何东西。我知道这是默认行为,但如何让 Mockery 运行相同/相似的回调?

我尝试过使用部分模拟,使用 shouldExpect 但没有完全理解它。我也试过四处搜索,但没有找到这种情况。

如果我能学习如何在回调中使用 mock ,那就太好了。

最佳答案

好吧,所以我认为这可以用更好的方法来完成,但我求助于部分模拟 Laravel 的查询构建器。

请参阅 Illuminate\Database\Query\Builder 中的第 324 行

当使用闭包时,Laravel 会生成一个新的查询构建器,它也需要被模拟。这是有效的代码:

$query = \Mockery::mock('Illuminate\Database\Query\Builder', function ($mock) {
    /** @var \Mockery\Mock $mock */
    $mock->makePartial();
    $mock->shouldReceive('where')->once()->passthru();
    $mock->shouldReceive('newQuery')->andReturn(
        \Mockery::mock('Illuminate\Database\Query\Builder', function ($mock) {
            /** @var \Mockery\Mock $mock */
            $mock->makePartial();
            $mock->shouldReceive('orWhere')->twice();
        })
    );
});

我需要使用 makePartial() 以便查询构建器保留其原始的闭包功能(这对于单元测试而言并非如此),因此这不是最佳解决方案。从这里我模拟了 newQuery 方法,该方法被调用以生成一个新的查询构建器实例,然后我以类似的格式模拟它。

关于php - Laravel 4 中的模拟回调(Mockery),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20701679/

相关文章:

c# - 在运行时加载依赖程序集时是否可以运行单元测试?

unit-testing - 使用 MockBackend 的 Angular 4 测试返回 Promise

php - Jquery/Ajax 表单提交(enctype ="multipart/form-data")。为什么 'contentType:False' 在 PHP 中会导致 undefined index ?

PHP在$_GET中使用时加密解密不起作用

php - : fill form, 的流程进行 Paypal 付款,创建帐户

javascript - mySqli php - 用户将多选复选框输入到 1 条记录中

java - 尝试模拟 get 类时出现 Mockito UnfinishedStubbingException

php - 我的 Composer 不会用 Laravel 4 完全更新它被 artisan 卡住了

Laravel 框架大小

php - Laravel 邮件无法从现场发送