AndyL

AndyL

GenServers - how to test with `capture_io`?

I’ve got a Genserver that writes messages to stdout. I can’t figure out how to test using capture_io. Documentation says By default, capture_io replaces the group_leader (:stdio) for the current process. Perhaps there is a Process.group_leader call that will make this work, but I haven’t been able to find it. Can anyone point me to a solution?

Here’s a failing test script…

#!/usr/bin/env elixir 

ExUnit.start()

defmodule MyGenServer do
  use GenServer

  def start_link(default \\ []) do
    GenServer.start_link(__MODULE__, default, name: __MODULE__)
  end

  def init(initial_state) do
    {:ok, initial_state}
  end

  def handle_call(:sayhi, _caller, state) do
    IO.puts("HI")
    {:reply, :ok, state}
  end
end

defmodule MyGenServerTest do
  use ExUnit.Case

  import ExUnit.CaptureIO

  test "GenServer responds to :sayhi call by writing 'HI' to stdout" do
    {:ok, pid} = MyGenServer.start_link()
    assert capture_io(fn -> GenServer.call(pid, :sayhi) end) == "HI\n"
  end
end

Marked As Solved

voughtdq

voughtdq

The problem is that you have to set the group leader first, which doesn’t seem possible with the way that capture_io/1 currently works:

# group leader is set before starting the GenServer, so this works
assert ExUnit.CaptureIO.capture_io(fn ->
  {:ok, pid} = MyGenServer.start_link()
  GenServer.call(pid, :sayhi)
  GenServer.stop(pid)
end) == "HI\n"

I wonder what the ideal way to do this would be. If we had some way of telling capture_io to use the pid of the GenServer, then it could properly set the group leader.

Maybe something like this:

{:ok, pid} = MyGenServer.start_link()
assert ExUnit.CaptureIO.capture_io([pid: pid], fn -> GenServer.call(pid, :sayhi) end)

Also Liked

voughtdq

voughtdq

Just a heads up that this will now be possible in v1.17.0:

assert ExUnit.CaptureIO.capture_io(pid, fn -> 
  GenServer.call(pid, :sayhi) 
end)
AndyL

AndyL

ityonemo

ityonemo

if you can’t wait for elixir 1.17, you can manually set the group_leader of the pid you want using :erlang.group_leader/2 to your test process and assert_receive on the messages that flow in.

Be careful! The order of the parameters on :erlang.group_leader/2 might not be the order you expect.

Last Post!

ityonemo

ityonemo

if you can’t wait for elixir 1.17, you can manually set the group_leader of the pid you want using :erlang.group_leader/2 to your test process and assert_receive on the messages that flow in.

Be careful! The order of the parameters on :erlang.group_leader/2 might not be the order you expect.

Where Next?

Popular in Questions Top

Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New

Other popular topics Top

KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36654 110
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54921 245
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 44532 311
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44139 214
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New

We're in Beta

About us Mission Statement