budgie
Can I stop swoosh test adapter from sending a message to self()?
Swoosh is mucking with a few of my tests. It looks like there is no configurability in the test adapter to change the behavior and get it to stop sending messages. Is there an alternative test adapter that people are using? Maybe the Logger adapter?
It would seem like a silly solution to implement a handle_info catch-all in my LiveView just to make the tests pass.
defmodule Swoosh.Adapters.Test do
@moduledoc ~S"""
An adapter that sends emails as messages to the current process.
This is meant to be used during tests and works with the assertions found in
the [Swoosh.TestAssertions](Swoosh.TestAssertions.html) module.
## Example
# config/test.exs
config :sample, Sample.Mailer,
adapter: Swoosh.Adapters.Test
# lib/sample/mailer.ex
defmodule Sample.Mailer do
use Swoosh.Mailer, otp_app: :sample
end
"""
use Swoosh.Adapter
def deliver(email, _config) do
for pid <- pids() do
send(pid, {:email, email})
end
{:ok, %{}}
end
def deliver_many(emails, _config) do
for pid <- pids() do
send(pid, {:emails, emails})
end
responses = for _email <- emails, do: %{}
{:ok, responses}
end
# Essentially finds all of the processes that tried to send an email (in the test)
# and sends an email to that process.
defp pids do
if pid = Application.get_env(:swoosh, :shared_test_process) do
[pid]
else
Enum.uniq([self() | List.wrap(Process.get(:"$callers"))])
end
end
end
First Post!
Eiji
Yes and no … Even if you cannot stop some process from sending any messages to self() then you can “silence” such messages by ensuring that self() is not a current test process. Consider simple example:
defmodule Example do
def sample1 do
send(self(), :ok)
notify(1)
end
def sample2 do
spawn(fn -> send(self(), :ok) end)
notify(2)
end
defp notify(step) do
receive do
:ok -> IO.puts("[#{step}/2] Received :ok")
after
1000 -> IO.puts("[#{step}/2] No message received")
end
end
end
Example.sample1()
Example.sample2()
When running this code using elixir example.exs we would got such result:
[1/2] Received :ok
[2/2] No message received
However if you have to send to self() only your messages then it’s also very easy to do, see:
defmodule Example do
def sample1 do
send(self(), "ok")
notify(1)
end
def sample2 do
parent_pid = self()
spawn(fn ->
send(self(), "example message from library")
send(parent_pid, "custom message")
end)
notify(2)
end
defp notify(step) do
receive do
message -> IO.puts("[#{step}/2] Received: #{message}")
after
1000 -> IO.puts("[#{step}/2] No message received")
end
end
end
Example.sample1()
Example.sample2()
After such changes here is what we’ve got in console:
[1/2] Received: ok
[2/2] Received: custom message
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









