【问题标题】:Mocking callbacks in Laravel 4 (Mockery)Laravel 4 (Mockery) 中的模拟回调
【发布时间】:2014-01-09 04:49:31
【问题描述】:

我目前正在为 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,但不完全理解。我也尝试过四处搜索,但没有运气。

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

【问题讨论】:

    标签: php unit-testing laravel-4 mockery


    【解决方案1】:

    好的,所以我认为这可以做得更好,但我采取了部分模拟 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 方法,该方法被调用以生成一个新的查询构建器实例,然后我以类似的格式模拟该实例。

    【讨论】:

    • 这对我很有帮助!我在 Mockery 文档中找不到任何关于将闭包作为第二个参数传递给 mock 的内容。你怎么知道这样做的?
    猜你喜欢
    • 2017-04-25
    • 2014-12-04
    • 2015-03-27
    • 2014-11-05
    • 2022-01-04
    • 2016-08-17
    • 2013-09-30
    • 2016-01-14
    • 2019-10-24
    相关资源
    最近更新 更多