jeudi 25 février 2021

PHPUnit how to test a Repository?

I have a group of Repository classes I'd like to test. All Eloquent methods are called in these classes, however I am unsure on how to proceed. The only thing that needs to be tested, is that the methods return the right data type. I want to be sure that getByEmail($email) for example actually returns a User object, but I don't care about the implementation details.

Every example I see tells you to inject the model in to the Repository class and mock it, then you can proceed by having that Mock expect very specific method calls. Is this the correct approach? Because it seems to me that would be forcing the developer to use very specific methods when building the Eloquent query.

Here's an example:

class UserRepository {
    public function __construct(User user) { ... }

    public function getByEmail(string $email) : ?User {
        $this->user->where('email', $email)->first();
    }
}

For the test with Mock to work I have to do:

class myTest {
    public function testMethodReturnsUserObject() {
        $user = Mockery::mock(User::class);

        $repo = new UserRepository($user);
        
        // now, if a developer changes the eloquent method calls, this will fail.
        $user->shouldReceive('where->first')->andReturn($user);

        $this->assertEquals($user, $repo->getByEmail('joe.bloggs@acme.com'));
    }
}

Any ideas what I should do to test that my method does indeed return a User object, without forcing the developer to use exactly one where() method, and one first() method in this example. What if the developer needs to instead make it ->select()->where()->where()->firstOrFail() . Now the unit test will break, even though it really shouldn't care about this, and only that the method returns a User.

Thanks!

Aucun commentaire:

Enregistrer un commentaire