Hi,
I'm glad you're enjoying the book
The :stop trick is used to
ensure that the server process is stopped from the test. Usually you don't need to do this. If you start your test processes with start_link, then they will terminate together with the test process. However, in this code I'm using start, so I need to do this manually.
It's worth mentioning that this solution is now obsolete. Since Elixir 1.2 and Erlang 18, there is
GenServer.stop available which can be used for this purpose, so no need to handle custom messages.
When it comes to your Stack Overflow question, it's not clear what exactly are you trying to test? Your test issues a cast and then stops. As the answer states, you could ensure that the cast is processed by issuing a synchronous request to the same process. There's no need to introduce special handlers in the server though. Invoking e.g.
:sys.get_state after in the test process after you send a message could help, because it will return after the previous message is processed.
However, I'd advise to think about the test purpose. The test in the SO question doesn't seem to test anything. Presumably you somehow want to test the outcome of App.Notifications.Manager.send. If you do that, then your test process can't exit before the cast is handled, because it is awaiting on its result.
How exactly will you verify the output of cast depends on a particular use-case. One solution is to send a notification message to interested parties. In your case, you'd need some kind of mechanism which would allow you to dynamically register your test process with your event manager. Then the test process would receive a notification message, and you could assert on it using
assert_receive. I tend to use such approach occasionally, and rely on the
gproc lib for dynamic pubsub. I explained it briefly near the end of my
talk on discovering processes.
Another approach is to use Erlang tracing capabilities to make the test process receive a message when some function is called and when it returns. I've described this idea
here. So in your test process you could setup a trace to the event manager, and assert that you receive a message when a function (e.g. handle_cast) returns. You can also find some related info in
this post on elixirforum.com and the subsequent comment by José.