仅针对某个参数模拟响应

时间:2017-01-09 14:56:25

标签: php laravel mockery

我有一个课程,当我使用get调用test1来回复123时,我会嘲笑get方法。这很好用。

但是,我希望对$configMock = m::mock(Config::class); $configMock->shouldReceive('get') ->with('test1') ->andReturn(123); 方法的所有其他调用返回通常返回的内容 - 即只有具有特定参数的调用才会返回模拟响应。

$config->get('test2')

因此,如果我在代码中使用其他参数调用get,即->makePartial(),我会收到错误

  

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

但是当我在第一行使用$config->get('test2')时,在{{1}}行我收到了错误

  

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

如何只为某个传递的参数模拟方法响应,同时让该方法为该方法的所有其他调用返回正常响应?

3 个答案:

答案 0 :(得分: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);
    }
}

这就是我相信你的问题,如果我弄错了,请告诉我!

答案 1 :(得分:0)

我最终接受了@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);

答案 2 :(得分:0)

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

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