Let’s image we have a class:
class EmailSender
{
public function send(Email $email): void
{
// your implementation
}
}
The Email
class will hold the details to the email you want to send:
class Email
{
public string $template;
public string $email;
//...
}
If you want to mock the EmailSender
you can do something like this:
...
class EmailSenderTest extends TestCase
{
public function testEmailSender()
{
$this->instance(
EmailSender::class,
Mockery::mock(EmailSender::class, function (MockInterface $mock) {
$mock->shouldReceive('send')
->withAnyArgs()
->once();
})
);
...
}
}
The approach above you are testing if the send
message is called once, but you haven`t tested if the argument provided to the method has the correct data on it.
To add checks on the object as well, you can assert it in the with
for a mocked object, as:
...
class EmailSenderTest extends TestCase
{
public function testEmailSender()
{
$this->instance(
EmailSender::class,
Mockery::mock(EmailSender::class, function (MockInterface $mock) {
$mock->shouldReceive('send')
->with(Mockery::on(function (Email $email) {
$this->assertEquals('my-template', $email->template);
$this->assertEquals('[email protected]', $email->email);
})->once();
})
);
...
}
}
This way your test is only going to pass if the Email
class has expected template and email properties.