Elixir Application.set_env和并发竞争条件

时间:2016-07-06 20:02:26

标签: concurrency erlang elixir race-condition gen-server

阅读我的代码中的http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/文章后:

  defp rest_adapter, do: Application.get_env(:app_name, :rest_adapter)

我在测试期间使用它来“模拟”休息适配器并返回不同的结果和错误代码。

但是,在这些测试中,存在竞争条件,因为我为不同的测试用例设置了不同的rest_adapter

有时它们按预期工作,但有时它们并没有“捕获”不同的rest_adapter设置,特别是对于此测试。

如何避免那个问题?

1 个答案:

答案 0 :(得分:0)

问题来自于应用程序环境是全局的 - 您无法在多个位置同时更改它以具有不同的值。 最简单的解决方案是通过删除async: true来禁用并发测试,但是会使测试速度变慢,因为它们无法同时运行。

幸运的是还有其他可能的解决方案。最简单的一个(可以说是最优雅的一个)是将适配器作为选项传递给使用它的函数,当没有提供时,使用应用程序环境中的那个。另一种解决方案是,当调用在同一进程中发生时(通常就是这种情况)是使用进程字典来传递适配器,而不是依赖于应用程序环境。

此外,可以调整混合解决方案,例如有两个适配器:真实的和一个返回来自流程字典的响应。然后在测试中始终使用进程字典,并在调用函数之前放置预期的响应。

最后有一些像Bypass这样的东西可以在一个稍微不同的层上工作,为你提供一个模拟的HTTP端点,而不是替换调用端点的代码(这是&#34的常用方法;替换&#34 ; http在测试中调用。)