Мокинг ответа только по определенному параметру

У меня есть класс, в котором я издеваюсь над методом get при вызове с test1 для возврата 123. Это нормально работает.

Однако я хочу, чтобы все остальные вызовы метода get возвращали то, что обычно возвращается, т.е. только вызов с определенным параметром возвращает фиктивный ответ.

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

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

Поэтому, если я вызываю get с другим параметром в коде, то есть $config->get('test2'), я получаю сообщение об ошибке

Mockery \ Exception \ NoMatchingExpectationException: не найдено подходящего обработчика для MockerygetIlluminate_Contracts_Config_Repository :: get ("test2"). Либо метод был неожиданным, либо его аргументы не соответствовали ожидаемому списку аргументов для этого метода

Однако, когда я использую ->makePartial() в первой строке, в строке $config->get('test2') я получаю сообщение об ошибке

BadMethodCallException: метод MockerygetIlluminate_Contracts_Config_Repository :: get () не существует для этого фиктивного объекта

Как я могу издеваться над ответом метода только для определенного передаваемого параметра, позволяя этому методу возвращать нормальные ответы для всех других вызовов этого метода?


person myol    schedule 09.01.2017    source источник


Ответы (3)


Я лично считаю, что нужно точно указывать, что вы хотите, в каждой тестовой функции. Итак, в основном это:

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

Думаю, именно об этом и был ваш вопрос, дайте мне знать, если я ошибаюсь!

person Loek    schedule 09.01.2017
comment
Спасибо, но я не хочу высмеивать каждый ответ этого метода, только один, когда передается определенный параметр. - person myol; 10.01.2017
comment
Так что издевайтесь над методом, если у вас есть параметр, и назовите его в противном случае? - person Loek; 10.01.2017
comment
Да, возможно ли это издевательством? Я почти уверен, что сделал это с помощью PHPUnit - person myol; 10.01.2017
comment
Просто используйте метод из моего ответа и замените часть else реальным вызовом функции? - person Loek; 10.01.2017
comment
Спасибо, что последнее предложение привело меня к решению - person myol; 10.01.2017

В итоге я последовал совету @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);
person myol    schedule 10.01.2017

Вы можете связать '- ›shouldReceive (' get ')' несколько раз и накормить >andReturn( тем, что вам действительно нужно на этот раз.

Вам следует избегать размещения какой-либо логики в модульном тесте, используя вместо этого порядок вызываемой функции.

person Yevgeniy Afanasyev    schedule 03.02.2021