Pau*_*nti 3 io elixir spawn ex-unit
我想在以下方法上测试返回值和IO输出:
defmodule Speaker do
def speak do
receive do
{ :say, msg } ->
IO.puts(msg)
speak
_other ->
speak # throw away the message
end
end
end
Run Code Online (Sandbox Code Playgroud)
在ExUnit.CaptureIO文档中,有一个示例测试,它执行此操作,如下所示:
test "checking the return value and the IO output" do
fun = fn ->
assert Enum.each(["some", "example"], &(IO.puts &1)) == :ok
end
assert capture_io(fun) == "some\nexample\n"
end
Run Code Online (Sandbox Code Playgroud)
鉴于此,我认为我可以编写以下测试,执行类似的操作但使用spawned过程:
test ".speak with capture io" do
pid = Kernel.spawn(Speaker, :speak, [])
fun = fn ->
assert send(pid, { :say, "Hello" }) == { :say, "Hello" }
end
assert capture_io(fun) == "Hello\n"
end
Run Code Online (Sandbox Code Playgroud)
但是,我得到以下错误消息告诉我没有输出,即使我可以在终端上看到输出:
1) test .speak with capture io (SpeakerTest)
test/speaker_test.exs:25
Assertion with == failed
code: capture_io(fun) == "Hello\n"
lhs: ""
rhs: "Hello\n"
stacktrace:
test/speaker_test.exs:30: (test)
Run Code Online (Sandbox Code Playgroud)
那么,我是否遗漏了一些关于测试spawned过程或使用receive宏的方法的问题?如何更改测试以使其通过?
CaptureIO可能不适合你在这里尝试做的事情.它运行一个函数,并在该函数返回时返回捕获的输出.但是你的功能永远不会返回,所以看起来这样不行.我提出了以下解决方法:
test ".speak with capture io" do
test_process = self()
pid = spawn(fn ->
Process.group_leader(self(), test_process)
Speaker.speak
end)
send(pid, {:say, "Hello"})
assert_receive {:io_request, _, _, {:put_chars, :unicode, "Hello\n"}}
# Just to cleanup pid which dies upon not receiving a correct response
# to the :io_request after a timeout
Process.exit(pid, :kill)
end
Run Code Online (Sandbox Code Playgroud)
它用于Process.group_leader将当前进程设置为测试进程的IO消息接收者,然后断言这些消息到达.
| 归档时间: |
|
| 查看次数: |
566 次 |
| 最近记录: |