I have a Phoenix app (which is just a restful api with no front end) and one of the controllers does some stuff which I want to test, but at the end of the controller it calls a dispatcher which sends a payload off to a worker (run under poolboy) to process the received payload in the background.
In my controller test, I don't actually want to test the stuff the worker is doing, I just want to know that the dispatcher for the worker has been called with the correct payload (e.g. calledWith() )
And ideally the dispatcher function to be stubbed, so the actual thing is never ran.
I could pass an additional parameter to the dispatcher to ensure it never runs the code on the worker, but that seems very messy, whereas a stub seems idea.
Thanks
Edit
Dispatcher code:
defmodule Convert.Dispatcher do
  def dispatch(data) fo
   spawn (fn() -> parallel(data) end)
  end
  def parallel(data) do
    #pass off to poolboy
  end
end
Test mock:
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
There is a mocking library called "mock" that you can use to temporarily mock modules in your tests. For example:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With