In every elm
file, dependencies to be imported are declared at the top.
Is there a way, while testing the application, to mock a dependency?
For example, suppose I have an application using the HTTP module to make an ajax request. When I test my module, I would like to avoid to make the actual ajax request, but I'd like to have a mocked HTTP module which will return a fake response just for the sake of testing.
How could I do this?
Since Elm is a pure functional language, you often don't need to do any kind of mocking because side effects are limited to interaction with ports. Most of the time, you can just call the function you want to test directly.
Consider this typical example of an HTTP request task being mapped to an Action:
type alias MyThing =
{ id : Int
, name : String
}
type Action
= FetchData
| ErrorOccurred String
| DataFetched MyThing
myDecoder : Json.Decoder MyThing
myDecoder =
Json.object2
MyThing
("id" := Json.int)
("name" := Json.string)
fetchData : Effects Action
fetchData =
Http.get myDecoder url
|> Task.toResult
|> Task.map httpResultToAction
|> Effects.task
httpResultToAction : Result Http.Error MyThing -> Action
httpResultToAction result =
case result of
Ok thing ->
DataFetched thing
Err err ->
ErrorOccurred (toString err)
There are a few things that would benefit from testing here, but none of them require mocking.
You may want to test the JSON decoding of myDecoder
. You could simply create some good and bad JSON strings and use Json.Decode.decodeString
with myDecoder
to test that the end result meets your expectation.
The thing that is probably most in need of unit testing is the httpResultToAction
function. Again, in this example, this requires no mocking. All you need to do is create a number of good and bad Result
values and test your expectations.
You should separate the code that calls into the Http module from the real logic you want to test.
For example, if you write a function that takes a Result Error String
as an argument (such as might come back from a call to Http.getString
) you can easily unit test that function without needing to make a real HTTP call.
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