【发布时间】:2016-02-01 15:51:35
【问题描述】:
在每个elm 文件中,要导入的依赖项声明在顶部。
有没有办法在测试应用程序时模拟依赖项?
例如,假设我有一个应用程序使用 HTTP 模块发出 ajax 请求。当我测试我的模块时,我想避免发出实际的 ajax 请求,但我想有一个模拟的 HTTP 模块,它会返回一个虚假的响应,只是为了测试。
我该怎么做?
【问题讨论】:
标签: ajax unit-testing elm
在每个elm 文件中,要导入的依赖项声明在顶部。
有没有办法在测试应用程序时模拟依赖项?
例如,假设我有一个应用程序使用 HTTP 模块发出 ajax 请求。当我测试我的模块时,我想避免发出实际的 ajax 请求,但我想有一个模拟的 HTTP 模块,它会返回一个虚假的响应,只是为了测试。
我该怎么做?
【问题讨论】:
标签: ajax unit-testing elm
由于 Elm 是一种纯函数式语言,您通常不需要进行任何类型的模拟,因为副作用仅限于与端口的交互。大多数时候,你可以直接调用你想测试的函数。
考虑这个将 HTTP 请求任务映射到 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)
这里有一些可以从测试中受益的东西,但它们都不需要模拟。
您可能想要测试myDecoder 的 JSON 解码。您可以简单地创建一些好的和坏的 JSON 字符串,并使用 Json.Decode.decodeString 和 myDecoder 来测试最终结果是否符合您的期望。
最需要单元测试的可能是httpResultToAction 函数。同样,在这个例子中,这不需要模拟。您需要做的就是创建一些好的和坏的Result 值并测试您的期望。
【讨论】:
fetchData?
fetchData 返回一个Effects 类型,它是Task 的浅包装。它实际上并不执行 HTTP 请求。您的测试将围绕剥离生成的 Effects 返回值并检查 Task 展开,但此时您的测试似乎更侧重于测试核心 Elm 代码,而不是实际测试您的应用程序。
|> 运算符的链接。但是,也许仅仅让它编译就足以证明它是有效的;测试其他部分才是价值所在。
mock-api-server 一起使用来模拟响应。
您应该将调用 Http 模块的代码与您要测试的真实逻辑分开。
例如,如果您编写一个以Result Error String 作为参数的函数(例如可能从对Http.getString 的调用中返回),您可以轻松地对该函数进行单元测试,而无需进行真正的HTTP 调用。
【讨论】: