Skip to content

Instantly share code, notes, and snippets.

@alexfaber2011
Created January 13, 2016 13:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexfaber2011/389132ce23d9a523d528 to your computer and use it in GitHub Desktop.
Save alexfaber2011/389132ce23d9a523d528 to your computer and use it in GitHub Desktop.
Testing Re-Frame Handlers that Dispatch Other Handlers
; I have a question about how to test handlers that dispatch other handlers (say when fetching from a server).
; Here's what the wiki says about fetching from servers
(ns my.app.handlers
(:require [ajax.core :refer [GET POST]]
[re-frame.core :refer [register-handler]))
(register-handler
:request-it
(fn
[db _]
(ajax.core/GET
"http://json.my-endpoint.com/blah"
{:handler #(dispatch [:process-response %1])
:error-handler #(dispatch [:bad-response %1])})
(assoc db :loading? true)))
; This approach relies on dispatching another re-frame handler (either `:bad-response` or `:process-response`).
; To test the `:request-it` handler the testing section in the wiki tells us to yank out the anonymous function
; which exposes it for testing like so:
(ns my.app.handlers
(:require [ajax.core :refer [GET POST]]
[re-frame.core :refer [register-handler]))
(defn request-it
[db _]
(ajax.core/GET
"http://json.my-endpoint.com/blah"
{:handler #(dispatch [:process-response %1])
:error-handler #(dispatch [:bad-response %1])})
(assoc db :loading? true)))
(register-handler
:request-it
request-it)
; The problem is we're only able to test what `request-it` returns which is an updated version of the app db
; that has it's `:loading?` flag set to true. What's the best way to test what's happening downstream, say
; after `:process-response` or `:bad-response` is called?
@alexfaber2011
Copy link
Author

Response by nberger on re-frame slack channel

  1. Keep the async behaviors during your test with the help of cljs.test/async and with-redefs to mock the get request (you don't want to hit the server, right?) but not mock dispatch.
  2. Remove all the async behavior by mocking dispatch, you could still test everything in one test (by calling bad-response or process-response yourself, in your redef'ed dispatch)

[8:34]
With the second approach you can get closer to "unit tests". In the first one you are heading to "integration tests". I usually prefer the first approach, so I'm also more confident that everything is orchestrated correctly, but I know others prefer the second one

[8:36]
Yesterday someone answered a similar question involving om components doing an async request during will-mount, it might help you as an example of using cljs.test/async and with-redefs: http://stackoverflow.com/questions/34116750/testing-components-with-async-api-calls-by-mocking-the-request

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment