Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5.4 Assert Mail Sent Not Working

I'm trying to assert mail sent with Laravel 5.4 fakes.

My test code is this:

public function setUp()
{
    parent::setUp();

    $this->admin = create(User::class, [
        'is_admin' => true,
    ]);

    $this->faker = Factory::create();
}

/** @test */
public function only_super_admin_can_create_admin()
{
    $admin = [
        'name'  => $this->faker->name,
        'email' => $this->faker->email,
    ];

    Mail::fake();

    $this->signIn($this->admin)
         ->post('/admins', $admin)
         ->assertRedirect('/admins');

    Mail::assertSent(NewUser::class, function ($mail) use ($admin) {
        dd($mail);
        // return $mail->hasTo($admin['email']);
    });

    $this->assertDatabaseHas('users', $admin);
}

When the $mail is dumped I am getting the following:

App\Mail\NewUser {#722
  #user: App\Models\User {#726
    #fillable: array:6 [
      0 => "name"
      1 => "email"
      2 => "password"
      3 => "role"
      4 => "is_admin"
      5 => "id"
    ]
    #hidden: array:2 [
      0 => "password"
      1 => "remember_token"
    ]
    #connection: "testing"
    #table: null
    #primaryKey: "id"
    #keyType: "int"
    +incrementing: true
    #with: []
    #withCount: []
    #perPage: 15
    +exists: true
    +wasRecentlyCreated: true
    #attributes: array:7 [
      "name" => "Dave Ortiz"
      "email" => "[email protected]"
      "password" => "$2y$10$OGiQJJ/HCOIlbAl/t6tbpuz4WLQenLRVZgFPN/0e0P.3Ft9542OW2"
      "is_admin" => true
      "updated_at" => "2017-06-03 11:06:56"
      "created_at" => "2017-06-03 11:06:56"
      "id" => 2
    ]
    #original: array:7 [
      "name" => "Dave Ortiz"
      "email" => "[email protected]"
      "password" => "$2y$10$OGiQJJ/HCOIlbAl/t6tbpuz4WLQenLRVZgFPN/0e0P.3Ft9542OW2"
      "is_admin" => true
      "updated_at" => "2017-06-03 11:06:56"
      "created_at" => "2017-06-03 11:06:56"
      "id" => 2
    ]
    #casts: []
    #dates: []
    #dateFormat: null
    #appends: []
    #events: []
    #observables: []
    #relations: []
    #touches: []
    +timestamps: true
    #visible: []
    #guarded: array:1 [
      0 => "*"
    ]
    #rememberTokenName: "remember_token"
  }
  #password: "ogDt9X87fM"
  +from: []
  +to: []
  +cc: []
  +bcc: []
  +replyTo: []
  +subject: null
  #markdown: null
  +view: null
  +textView: null
  +viewData: []
  +attachments: []
  +rawAttachments: []
  +callbacks: []
  +connection: null
  +queue: null
  +delay: null
}

As you can see, it is showing nothing in the to array which means when I assert that the Mail was sent with hasTo() it fails:

1) Tests\Feature\SuperAdminTest::only_super_admin_can_create_admin
The expected [App\Mail\NewUser] mailable was not sent.
Failed asserting that false is true.

My Controller stores the user as follows:

public function store(StoreUserRequest $request)
{
    $user = $request->storeUser(null, null, null, true);
    return redirect('/admins');
}

The StoreUserRequest method is as follows:

public function storeUser($name = null, $email = null, $password = null, $admin = false)
{
    $password = $password ?: str_random(10);
    $user = User::create([
                             'name'     => ($name) ?: $this->name,
                             'email'    => ($email) ?: $this->email,
                             'password' => bcrypt($password),
                             'is_admin' => $admin,
                         ]);

    Mail::send(new NewUser($user, $password));

    return $user;
}

The actual NewUser mailable is as follows:

class NewUser extends Mailable
{
    use Queueable, SerializesModels;

    protected $user;

    protected $password;

    /**
     * Create a new message instance.
     *
     * @param $user
     * @param $password
     */
    public function __construct($user, $password)
    {
        $this->user = $user;
        $this->password = $password;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.users.' . strtolower(($this->user->is_admin) ? 'Admin' : 'Client'))
                    ->with('user', $this->user)
                    ->with('password', $this->password)
                    ->to($this->user->email, $this->user->name)
                    ->subject('[' . $this->user->name . '] Your New ' . ($this->user->is_admin ? 'Admin' : 'Client') . ' Account');
    }
}

Now what makes this even more weird is when I manually create a user on the app, the email will arrive! Email Arrives

Does anyone have any ideas why this won't work?

like image 855
Shiv Avatar asked Oct 17 '22 11:10

Shiv


1 Answers

You should attach to outside of the mailable, just like in the documentation:

StoreUserRequest

Mail::to($user->email)->send(new NewUser($user, $password));

NewUser

public function build() {
    $account_type = $this->user->is_admin ? 'Admin' : 'Client';
    return $this->view('emails.users.' . strtolower($account_type)
        ->with([
            'user' => $this->user,
            'password' => $this->password
        ])
        ->subject("[${this->user->name}] Your New ${account_type} Account");
}
like image 89
Dov Benyomin Sohacheski Avatar answered Oct 21 '22 07:10

Dov Benyomin Sohacheski