Concurrency Elixir Application.set_env和并发争用条件

Concurrency Elixir Application.set_env和并发争用条件,concurrency,erlang,elixir,race-condition,gen-server,Concurrency,Erlang,Elixir,Race Condition,Gen Server,在阅读了我的代码中的文章后: defp rest_adapter, do: Application.get_env(:app_name, :rest_adapter) 我使用它在测试期间“模拟”rest适配器,并返回不同的结果和错误代码 然而,在这些测试过程中,存在竞争条件,因为我为不同的测试用例设置了不同的rest\u适配器 有时它们按预期工作,但有时它们不会“捕获”专门为此测试设置的不同的rest\u适配器 如何避免出现这个问题?这个问题源于应用程序环境是全局的,您不能在多个位置同时更

在阅读了我的代码中的文章后:

  defp rest_adapter, do: Application.get_env(:app_name, :rest_adapter)
我使用它在测试期间“模拟”rest适配器,并返回不同的结果和错误代码

然而,在这些测试过程中,存在竞争条件,因为我为不同的测试用例设置了不同的
rest\u适配器

有时它们按预期工作,但有时它们不会“捕获”专门为此测试设置的不同的
rest\u适配器


如何避免出现这个问题?

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

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

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


最后,在稍微不同的层上有类似的工作,为您提供一个模拟的HTTP端点,而不是替换用于调用端点的代码(这是测试中“替换”HTTP调用的常用方法).

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

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

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


最后,在稍微不同的层上有类似的工作,为您提供一个模拟的HTTP端点,而不是替换用于调用端点的代码(这是测试中“替换”HTTP调用的常用方法).

您是否使用
async:true
运行测试?我尝试过使用和不使用它。您是否使用
async:true
运行测试?我尝试过使用和不使用它。