I set the sender in my mailable class, and I want to write a simple test to make sure the mail is sent by the correct sender. However, the Mailable->hasFrom always return false. and I dump the $mail in my test, the from property is empty.
<?php
// My mailable class
namespace App\Mail;
use Illuminate\Mail\Mailable;
class MyMail extends Mailable
{
public function build()
{
return $this->from('[email protected]')
->text('test mail');
}
}
<?php
// My Test class
namespace Tests\Unit;
use App\Mail\MyMail;
use Illuminate\Support\Facades\Mail;
use Tests\TestCase;
class MyMailTest extends TestCase
{
/** @test */
public function the_email_with_correct_sender()
{
Mail::fake();
$myMail = new MyMail();
Mail::to('[email protected]')
->send($myMail);
Mail::assertSent(MyMail::class, function ($mail) {
return $mail->hasFrom('[email protected]');
});
}
}
I'm running into what I think is the same issue. I post this about this a few days ago to. One of the contributors @themsaid just closed it because I had Laravel 5.3.31 installed and he said it wasn't supported and closed my thread. After that another developer posted that his wasn't working on 5.4 and I upgraded my framework to 5.4 and it still throws the exact same error.
I've also seen other threads about this, none of which were solved so I could get an answer. @taylorotwell
This is my post which shows the error I get.https://github.com/laravel/framework/issues/20059
I did some testing it happens because of the build method not being triggered when you use MailFake if you use the following code it would work this is not a fix of course...
```
// My Test class
namespace Tests\Unit;
use App\Mail\MyMail;
use Illuminate\Support\Facades\Mail;
use TestsTestCase;
class MyMailTest extends TestCase
{
/** @test */
public function the_email_with_correct_sender()
{
Mail::fake();
$myMail = new MyMail();
Mail::to('[email protected]')
->send($myMail);
Mail::assertSent(MyMail::class, function ($mail) {
$mail->build(); // <-- add this
return $mail->hasFrom('[email protected]');
});
}
}
```
The code in the MailFake looks as follows
/**
* Send a new message using a view.
*
* @param string|array $view
* @param array $data
* @param \Closure|string $callback
* @return void
*/
public function send($view, array $data = [], $callback = null)
{
if (! $view instanceof Mailable) {
return;
}
$this->mailables[] = $view;
}
As you can see if you pass it a mailable it will just return and do nothing while the Mailable real method will call the build method.
Thanks @Douglasdc3, my simple test pass after added $mail->build().
Hello @nivanmorgan has your problem been solved by @Douglasdc3's solution?
@wadleo The problem solved by @Douglasdc3 solution.
Ok cool
On Jul 24, 2017 3:05 AM, "Gump Lei" notifications@github.com wrote:
@wadleo https://github.com/wadleo The problem solved by @Douglasdc3
https://github.com/douglasdc3 solution.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/laravel/framework/issues/20056#issuecomment-317301794,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AKfxRE88ebWTquEttR5hh7QZqfwhMkDNks5sQ_vzgaJpZM4OXv3R
.
Hi, I run into the same issue and @Douglasdc3's solution works.
But is there a good reason to not include this directly in the framework, in MailFake::send ?
/**
* Send a new message using a view.
*
* @param string|array $view
* @param array $data
* @param \Closure|string $callback
* @return void
*/
public function send($view, array $data = [], $callback = null)
{
if (! $view instanceof Mailable) {
return;
}
// Call build here fix the problem
$this->mailables[] = $view->build();
}
Most helpful comment
I did some testing it happens because of the
buildmethod not being triggered when you useMailFakeif you use the following code it would work this is not a fix of course...``` // My Test class
namespace Tests\Unit;
use App\Mail\MyMail;
use Illuminate\Support\Facades\Mail;
use TestsTestCase;
class MyMailTest extends TestCase
{
/** @test */
public function the_email_with_correct_sender()
{
Mail::fake();
$myMail = new MyMail();
Mail::to('[email protected]')
->send($myMail);
Mail::assertSent(MyMail::class, function ($mail) {
$mail->build(); // <-- add this
return $mail->hasFrom('[email protected]');
});
}
}
```
The code in the
MailFakelooks as followsAs you can see if you pass it a mailable it will just return and do nothing while the
Mailablereal method will call thebuildmethod.