Как мне использовать shouldReceive для функции, которая была вызвана другим?

#php #laravel #mocking #laravel-5.4 #mockery

#php #laravel #издевательство #laravel-5.4

Вопрос:

У меня есть функции, подобные so:

 // $value could be an array or SomeClass type
public function foo($key, $value) 
{
    // some code
    if ($value instanceof SomeClass) {
        $value = $this->bar($value);
    }
    // some code
}

protected function bar(SomeClass $value) 
{
    // do stuff
}
  

Теперь в моем тесте у меня есть что-то вроде этого:

 {
    $suppliedValue = [];

    $mock = ... // create mock
    $mock->shouldReceive('foo')->withArgs(
        // first arg should be an int or string
        // second arg should be an array or SomeClass object
    );

    if (typeOf($suppliedValue) === 'array') {
        $mock->shouldNotReceive('bar');
    } else {
        $mock->shouldReceive('bar');
    }

    $mock->aFunctionThatCallsFoo($suppliedValue);
}
  

Однако, похоже, это не работает, независимо от того, какое значение задано foo() , оно не запускает shouldReceive() / shouldNotReceive() on bar() .

Чего мне здесь не хватает? У меня такое чувство, как будто я неправильно понимаю что-то фундаментальное в mocking.

Ответ №1:

Я не нашел способа решить это с помощью mock, но вместо этого я использовал Spy.

 
$spy = Mockery::spy(TheClass::class)
              ->makePartial()
              ->shouldAllowMockingProtectedMethods();

$spy->aFunctionThatCallsFoo($suppliedValue);
$spy->shouldHaveReceived('foo')
    ->withArgs(/* args */); 
$spy->shouldHaveReceived('bar');
  

В итоге я создаю 2 тестовые функции вместо использования if else для типа $suppliedValue , где другая вызывает shouldNotHaveReceived()