【问题标题】:Mocking the response only for a certain parameter仅针对某个参数模拟响应
【发布时间】:2017-05-23 20:58:20
【问题描述】:

我有一个类,当使用test1 调用以返回123 时,我正在模拟get 方法。这工作正常。

但是,我希望对 get 方法的所有其他调用返回通常返回的内容 - 即只有具有特定参数的调用返回模拟响应。

$configMock = m::mock(Config::class);

$configMock->shouldReceive('get')
        ->with('test1')
        ->andReturn(123);

因此,如果我在代码中使用不同的参数调用 get,即 $config->get('test2'),我会收到错误

Mockery\Exception\NoMatchingExpectationException:没有为 Mockery_1_Illuminate_Contracts_Config_Repository::get("test2") 找到匹配的处理程序。该方法是意外的,或者它的参数与该方法的预期参数列表不匹配

但是,当我在第一行使用->makePartial() 时,在$config->get('test2') 行出现错误

BadMethodCallException:此模拟对象上不存在方法 Mockery_1_Illuminate_Contracts_Config_Repository::get()

我怎样才能模拟一个方法响应,只传递一个特定的参数,同时让该方法返回对该方法的所有其他调用的正常响应?

【问题讨论】:

    标签: php laravel mockery


    【解决方案1】:

    我个人认为应该准确地指定您希望在每个测试功能中发生什么。所以基本上就是:

    $configMock->shouldReceive('get')
               ->with('test2')
               ->andReturn(INSERT_CORRECT_RESPONSE);
    

    请注意,如果您有很多测试函数执行此操作,这会导致相当多的代码重复,因此您可能希望将其提取到另一个方法:

    private function testCorrectResult($parameter)
    {
        $configMock = m::mock(Config::class);
    
        if ($parameter === 'test1') {
            $configMock->shouldReceive('get')
                       ->with('test1')
                       ->andReturn(123);
        } else {
            $configMock->shouldReceive('get')
                       ->with('test2')
                       ->andReturn(INSERT_CORRECT_RESPONSE);
        }
    }
    

    这就是我认为您的问题所针对的,如果我弄错了,请告诉我!

    【讨论】:

    • 谢谢,但我不想模拟此方法的每一个响应,只模拟传递某个参数时的一个响应。
    • 如果有参数就模拟方法,否则正常调用?
    • 是的,可以使用嘲讽吗?我几乎可以肯定我已经使用 PHPUnit 完成了
    • 就用我回答中的方法,把else部分换成真正的函数调用?
    • 感谢最后的建议让我找到了解决方案
    【解决方案2】:

    我最终接受了@Loeks 的建议。可能有更清洁的方法可以做到这一点,但这对我有用。

        $config = new Config;
    
        $closure = function ($arg) use ($config) {
            switch ($arg) {
                case 'test1':
    
                    return 123;
                default:
                    // Return default values
    
                    return $config->get($arg);
            }
        };
    
        $configMock = m::mock(Config::class)
            ->makePartial();
    
        $configMock->shouldReceive('get')
            ->andReturnUsing($closure);
    

    【讨论】:

      【解决方案3】:

      您可以多次链接 '->shouldReceive('get')' 并为 >andReturn( 提供这次您真正需要的内容。

      您应该避免使用被调用函数的顺序将任何逻辑用于单元测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-27
        • 2016-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-12
        • 1970-01-01
        相关资源
        最近更新 更多