This weekend I read a post titled "Don't use Mocking libraries" by Crell and I think it's a gold nugget.
I will just make an overview of it to show you how powerful and clever solution he is proposing us.
Mock libraries are great but we can achieve the same feature with just plain PHP giving an:
- Easier reading and understanding of our code.
- Better performance.
- Less dependencies (oh yes please, less composer packages to keep up to date).
Example
We have a UserRepository
we need to mock to make our Unit Tests without coupling with infrastructure layer (MySQL, SQLite...)
Let's show our scenario:
class User
{
private string $id;
public function __construct(string $id)
{
$this->id = $id;
}
public function id()
{
return $this->id;
}
}
interface UserRepository
{
public function findById(string $id): User;
}
// An example implementation of our repository.
// not required for our example.
class InMemoryUserRepository implements UserRepository
{
private array $users;
public function findById(string $id): User
{
return $this->users[$id];
}
}
Well, it's time to mock it to run our tests. We just need to create a class that mocks our UserRepository
$userRepositoryMock = new class implements UserRepository
{
public function __construct() {}
public function findById(string $id): User
{
switch($id) {
case '1':
return new User('1');
case '2':
return new User('2');
}
throw new \Exception('Not found');
}
};
Boom! just using an anonymous class and implementing our interface we have the UserRepository
mocked and ready to test
public function itShouldTestSomething(): void
{
$user = $userRepositoryMock->findById('1');
$this->assertEquals('1', $user->id());
}
Conclusion
It's usual to look for libraries / packages that help us to implement some feature to avoid reinventing the wheel and save some time but this is (sometimes) not necessary and easily achieve with just pure PHP.
Top comments (0)