2015-06-15 24 views
6

我有一个凤凰应用程序(这只是一个没有前端的安静的api),其中一个控制器做了一些我想测试的东西,但是在控制器结束时它调用了一个调度器,一名工作人员(在poolboy下运行)在后台处理收到的有效负载。在我的控制器测试中,我实际上并不想测试工作人员正在做的事情,我只想知道工作人员的调度程序已被调用了正确的有效负载(例如,称为With())如何在我的ExUnit测试中对工作人员进行调用(或阻止运行)?

理想情况下,调度程序的功能被扼杀,所以实际的东西永远不会跑。

我可以传递一个额外的参数给调度员,以确保它永远不会在worker上运行代码,但这看起来非常混乱,而一个存根似乎是想法。

感谢

编辑

调度代码:

defmodule Convert.Dispatcher do 
    def dispatch(data) fo 
    spawn (fn() -> parallel(data) end) 
    end 

    def parallel(data) do 
    #pass off to poolboy 
    end 
end 

测试模拟:

with_mock Convert.Dispatcher, [dispatch: fn(_opts) -> :ok end] do 
    response = conn(:post, "/", data) |> send_request 
    body = response.resp_body |> Poison.decode! 
    assert response.status == 201 
    assert called Convert.Dispatcher.dispatch("") 
end 
+1

在考虑其他选项之前,请小心直接嘲笑图书馆。它可以防止同时运行该测试用例(由于全局修改模块),紧密耦合您的实现,这意味着当您需要与另一个模块交换并引入新的依赖关系时需要进行更多的工作。考虑注入你的依赖,而不是像http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/和https://medium.com/@lasseebert/mocks-in-elixir- 7204f8cc9d0f – Dennis

回答

7

有一个叫"mock"嘲弄库,你可以用它来暂时模拟模块在你身上r测试。例如:

defmodule MyControllerTest do 
    use ExUnit.Case, async: false 
    use RouterHelper 
    import Mock 

    setup do 
    Logger.disable(self()) 
    :ok 
    end 

    test "dispatches a worker" do 
    with_mock MyDispatcher, [dispatch: fn(_opts) -> :ok end] do 
     call(Router, :get, "/my/route") 
     assert called MyDispatcher.dispatch(foo: "bar") 
    end 
    end 
end 
+0

谢谢,这看起来不错,我会给它去一个 – TheStoneFox

+0

问题我得到的是模拟工作正常(即代码不运行),但当我尝试并做断言时,我得到的错误“预期truthy ,得到错误“ - 但我知道代码执行,因为我看到它输出之前添加模拟:/ – TheStoneFox

+0

你确定它被调用期望的参数? –

相关问题