2016-06-27 3 views
2

からIOをキャプチャ:ExUnit.CaptureIO docsテストは、私は次のような方法での戻り値とIO出力をテストしたい子プロセス

defmodule Speaker do 
    def speak do 
    receive do 
     { :say, msg } -> 
     IO.puts(msg) 
     speak 
     _other -> 
     speak # throw away the message 
    end 
    end 
end 

、これを行う例のテストがあり、次のように見えました

::私は、私は同様のアクションを実行しますが spawnエド・プロセスでは、次のテストを書くと考えていた、ということを考えると

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 

私はspawn EDプロセスをテストに関して、おそらく何かが足りないのです、だから、

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) 

はしかし、私は何も出力はありませんでした次のエラーメッセージが、私は端末に出力を見ることができるにもかかわらず、私に言ってもらいますまたはreceiveマクロを使用する方法テストを通過させるためにテストを変更するにはどうすればよいですか?

答えて

2

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 

それは、テストプロセスのIOメッセージの受信機として現在のプロセスを設定するProcess.group_leaderを使用して、これらのメッセージが到着すると主張しています。

+0

TILについて['Process.group_leader/2'](http://elixir-lang.org/docs/stable/elixir/Process.html#group_leader/2)、テストに合格したことを確認できますそれらの+1。他の誰かが回避策を講じていないかどうかを確認するために少し質問を残しておきます。ありがとう! –

関連する問題