How to clear a mailbox in channelcase phoenix framework test
Asked Answered
L

3

7

I am doing a channel test that is receiving lots of messages. I may receive a message during setup, adjust some state and then I want to assert ( or refute ) another copy of that message was sent. I think I could do this by clearing the mailbox before causing the event which would trigger the second message. How do I clear the channelcase mailbox?

EDIT, I have accomplished my needs by assert_push all of the old messages, which clears them off of the mailbox. This works well enough but would be very inconvenient if there were more than a few messages

Laburnum answered 19/10, 2016 at 19:41 Comment(0)
D
2

Edit: :lib.flush_receive() works perfectly! Unfortunately it looks like the module has been deprecated and I can't find a replacement.

I've been searching for a solution to this. assert_push isn't practical for me as there are many messages that are queued and not relevant to my test. You can use :c.flush() which dumps all the messages. Unfortunately I don't yet know how to prevent this from printing it out to the console.

Denazify answered 17/9, 2017 at 20:24 Comment(5)
have you tried hexdocs.pm/ex_unit/ExUnit.CaptureIO.html#content ?Laburnum
I haven't. How would this help?Denazify
"Unfortunately I don't yet know how to prevent this from printing it out to the console." not sure if your edit solved this problem, but I believe CaptureIO could prevent the messages from printing in the consoleLaburnum
Oh I see what you mean. I could try that yeah. the :lib.flush_receive() that I edited in solves the issue for now. If that goes away in the next erlang update I may try the CaptureIO you mentioned.Denazify
yeah, capture_io(fn -> :c.flush() end) prevents the messages from being loggedBonfire
I
2

An easy way to accomplish this is to simply receive the %Phoenix.Socket.Message{}.

For example:

def flush_messages(timeout \\ 100) do
  receive do
    %Phoenix.Socket.Message{} ->
      flush_messages()
  after
    timeout -> nil
  end
end

The timeout is there to allow pending messages to arrive. 100m is also the default timeout for assert_receive, which is being used by assert_push.

Igloo answered 1/6, 2018 at 13:8 Comment(0)
S
2

Just to clarify if anyone likes me gets quite confused with this problem.

The messages sent through the channel are stored at the test process mailbox, so in order to clean the messages we just need to clean the mailbox of the process. So using what Mark posted above we can flush the messages.

P.D: Using this :erlang.process_info(self(), :messages) |> IO.inspect() we can see the current messages at the process mailbox.

Sgraffito answered 1/4, 2019 at 10:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.