Testing the object you pass in a mocked method
Let's image we have a class:
1class EmailSender2{3 public function send(Email $email): void4 {5 // your implementation6 }7}
The Email
class will hold the details to the email you want to send:
1class Email2{3 public string $template;4 5 public string $email;6 7 //...8}
If you want to mock the EmailSender
you can do something like this:
1... 2 3class EmailSenderTest extends TestCase 4{ 5 public function testEmailSender() 6 { 7 $this->instance( 8 EmailSender::class, 9 Mockery::mock(EmailSender::class, function (MockInterface $mock) {10 $mock->shouldReceive('send')11 ->withAnyArgs()12 ->once();13 })14 );15 16 ...17 }18}
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:
1... 2 3class EmailSenderTest extends TestCase 4{ 5 public function testEmailSender() 6 { 7 $this->instance( 8 EmailSender::class, 9 Mockery::mock(EmailSender::class, function (MockInterface $mock) {10 $mock->shouldReceive('send')11 ->with(Mockery::on(function (Email $email) {12 $this->assertEquals('my-template', $email->template);14 })->once();15 })16 );17 18 ...19 }20}
This way your test is only going to pass if the Email
class has expected template and email properties.