2016-09-29 8 views
3

エリクシールで基本的なコードテストを習得しようとしていて、非同期関数のテスト(genserverのhandle_infoとキャスト)の周りに頭を下げるのに問題があります。GenServer非同期統合テスト

動作するが間違っている方法の1つは、非同期機能のキャスト後に:timer.sleep(x)を使用することです。

例えば、ステートからのアイテムのリストを処理し、外部APIからデータをフェッチする別のモジュールへの呼び出しをディスパッチし、メッセージ(apiデータ)を同じgenserverに送り返すと想像してください。

これをテストするにはどうすればよいでしょうか?テスト中のgenserverメッセージ/メールボックスを監視できますか?

編集: 別の例に、initに私がDBから初期状態を取得するには、この操作を行うと言う:

Process.send_after(self(), :started, 0) 

そして:は次のようになりました:

defhandleinfo :started, state: state, do: new_state(UserServerStarted.get_data(state)) 

を私は他のを持っていますかオプション:UserServerStartedが正しいものを返したかどうかを確認するtimer.sleep?私はモジュール/ユニットを別々にテストすることができますが、完全な統合テストをしたいと思います。

... SETUP - Supervisor start UserServer... 

    test "spin up server and inital tree after user registers", % 
    {user: user} do 
    :timer.sleep(500) 
    assert %{"default" => [nil]} == GenServer.call(UserServer.via_tuple(user.id), :get) 
    end 
+0

あなたは 'Process.infoを使用してメールボックスのメッセージを取得することができます(PID 、:messages) 'というメッセージが表示されますが、以前のメッセージを処理していない限り、GenServerがメッセージを受信すると直ちにそのメッセージを処理するため、これはGenServerと確実には機能しません。 – Dogbert

答えて

2

私は最近、同様の問題で苦労している:ここで

は、私は今それをやっている方法です。私はテストでの追跡を維持するプロセスを登録することにより、それを動作するように管理さ:

defmodule Foo 
    def bar do 
    pid = spawn fn -> consume(channel, tag, payload) end 
    if !Process.whereis(:worker) do 
     Process.register(pid, :worker) 
    end 
    end 
end 

そして、あなたのテストで:

test "bar" do 
    # < Setup code that triggers your process under test goes here > 

    # I put this here because I noticed that sometimes the process would not be 
    # fast enough to be registered - this was a quick fix. 
    :timer.sleep(100) 

    ref = Process.monitor(Process.whereis(:worker)) 

    # assert_receive will block the test until your registered process exits, 
    # or 10 seconds have passed (then something is wrong with the external service perhaps and the test will fail) 
    assert_receive {:DOWN, ^ref, :process, _, :normal}, 10000 

    # At this point the process has exited, continue with whatever assertions you want to make 
end 
関連する問題