search

Home  >  Q&A  >  body text

Issues using partial mocking in Laravel 9.x

<p>Hey laravel developers, I found an issue with partial mocking, I need to test a method that uses an internal method, which needs to be mocked, I tried using several methods to mock the method, like next idea: < ;/p> <pre class="brush:php;toolbar:false;">#1 $mockMyClass = Mockery::mock( $myClassInstance )->makePartial(); #2 $mockMyClass = $this->partialMock(); #3 $mockMyClass = $this->createPartialMock(); // and then $mockMyClass->shouldReceive('internalMethod') ->andReturn($responseInternalMethod);</pre> <p>And obviously using the way described in the documentation Laravel Mocking Objects</p> <pre class="brush:php;toolbar:false;">use App\Service; use Mockery\MockInterface; $mock = $this->partialMock(Service::class, function (MockInterface $mock) { $mock->shouldReceive('process')->once(); });</pre> <p>None of these ideas work, $mockMyClass always executes the real method, not the mock method that should return $responseInternalMethod. Does anyone have this problem too? I need to confirm if it's an issue with Laravel, Mockito, or externally, and not the local environment, haha. I read you! </p> <p>Technical details: Laravel 9.x PHP 8.1 PHP Unit 9.5 Taunt 1.5</p>
P粉726234648P粉726234648455 days ago533

reply all(1)I'll reply

  • P粉885035114

    P粉8850351142023-09-03 17:16:49

    Okay, I found the solution, but anyway, I'm interested to know if anyone has this problem too

    My solution to this problem is:

    public function testRealExternalMethod()
    {
        // Create a mock of the dependency that will be used by the class
        $mockDependency = $this->createMock(Dependency::class);
        
        // in this case we need to use a partial mock because we have an internal method
        $mockMyClass = Mockery::mock(
            MyClass::class,
            [$mockDependency, $parameter1]
        )
            ->makePartial();
    
        $responseInternalMethod = ['needed data'];
    
        $mockMyClass->shouldReceive('internalMethod')
            ->andReturn($responseInternalMethod);
    
        $result = $mockMyClass->realExternalMethod($parameter2, $parameter3);
    }
    The solution for these cases is to directly create a mock instance of my class and pass all parameters required by the constructor as dependencies or data. Then continue the testing loop using the mock class as the real class.

    reply
    0
  • Cancelreply