在Elixir中测试异步代码
我想测试一个使用在Elixir中测试异步代码,elixir,Elixir,我想测试一个使用Task.async 为了使我的测试通过,我需要在断言之前让它休眠100毫秒,否则测试进程在异步任务执行之前被终止 有更好的办法吗 已编辑,正在添加代码示例: 我想测试的代码(大致): 以及我已经编写的测试(仅在调用睡眠时使用) 由于这个问题有点模糊,我将在这里给出一般性的回答。通常的技术是监视进程并等待停机消息。大概是这样的: task = Task.async(fn -> "foo" end) ref = Process.monitor(task.pid) asser
Task.async
为了使我的测试通过,我需要在断言之前让它休眠100毫秒,否则测试进程在异步任务执行之前被终止
有更好的办法吗
已编辑,正在添加代码示例:
我想测试的代码(大致):
以及我已经编写的测试(仅在调用睡眠时使用)
由于这个问题有点模糊,我将在这里给出一般性的回答。通常的技术是监视进程并等待停机消息。大概是这样的:
task = Task.async(fn -> "foo" end)
ref = Process.monitor(task.pid)
assert_receive {:DOWN, ^ref, :process, _, :normal}, 500
一些重要的事情:
- 元组的第五个元素是退出原因。我断言任务出口是
。如果您希望再次退出,请相应地更改:normal
中的第二个值是超时。如果你现在有100毫秒的睡眠时间,500毫秒听起来是一个合理的时间assert\u receive
assert\u receive
)时,我会使用一个小助手重复执行断言/睡眠,直到断言通过或最终超时
这是帮助器模块
defmodule TimeHelper do
def wait_until(fun), do: wait_until(500, fun)
def wait_until(0, fun), do: fun.()
def wait_until(timeout, fun) defo
try do
fun.()
rescue
ExUnit.AssertionError ->
:timer.sleep(10)
wait_until(max(0, timeout - 10), fun)
end
end
end
在前一个示例中可以这样使用:
TSearch.search([q: "my query"])
wait_until fn ->
assert called TStore.store("some tweet from my fixtures")
assert called TStore.store("another one")
end
你能给我们展示一个最小的失败例子来说明你想做的断言的具体类型吗?示例代码将非常有助于给你一个好的答案。好的,刚刚添加的代码示例对我的代码的任何其他评论都是可以的:)(特别是模拟部分)如果你不打算使用任务的结果,不要使用task.async/1,您可以直接使用Task.start_link/1。谢谢您,José!刚刚在我的问题中添加了一些代码示例。我想我需要使用搜索函数来返回包含任务pid的元组?(我不喜欢仅仅为了测试目的而更改代码:/)让我来支持这一点。作为应用程序的任何其他部分,测试都是代码的使用者。确保为测试提供正确的结果通常是一个很好的指标,表明应用程序的其他部分也会正确使用该代码。例如,查看测试,我不知道返回结果是什么。如果我达到API限制会发生什么?如果我不这么做会怎么样?这个函数似乎是关于副作用的,返回一个任务会表明:嘿,我稍后会完成这个任务,如果你关心这个任务,请观看。
defmodule TimeHelper do
def wait_until(fun), do: wait_until(500, fun)
def wait_until(0, fun), do: fun.()
def wait_until(timeout, fun) defo
try do
fun.()
rescue
ExUnit.AssertionError ->
:timer.sleep(10)
wait_until(max(0, timeout - 10), fun)
end
end
end
TSearch.search([q: "my query"])
wait_until fn ->
assert called TStore.store("some tweet from my fixtures")
assert called TStore.store("another one")
end