Mocking and manipulating function behaviors

Hi,
I have a module like this:

 defmodule Services do
  @mailer Application.get_env(:app, :mailer)

  def signup_user(attrs) do
    with {:ok, %User{} = user} <- Accounts.create_user(attrs) do
      send_activation_email(user)
    end
  end

  def send_activation_email(%User{}=user) do
    token = blahh....

    case Email.Activation.message(user.email, token)
      |> @mailer.deliver_later do
          %Bamboo.Email{} -> {:ok, user}
          _ -> {:error, Constants.failed()}
      end
  end

end

Here, I have my Services module depending on Comm.Mailer module. With mocking, I am able to inject a mocked Mailer through test cases. However, what I want to do is test this method in various circumstances, here I see two:

  • when @mailer.deliver_later returns {:ok, user}
  • when @mailer.deliver_later returns {:error, “failed” }

My question is how do I make the deliver_later in the mock I injected behave in different ways to fit to each of my test case? ( Here I have only two, but there can be more depending on how many paths the code is following ). Also to note, I have tried Mox, but it seem to only work on Behaviors? Clearly here, my Comm.Mailer is not a behavior. It is merely useing the Bamboo modules from the Bamboo library.

defmodule Comm.Mailer do
  use Bamboo.Mailer, otp_app: :app
end

Can someone throw some light on this? thanks a lot!

Did some more research and I found a nice answer here