gpt4 book ai didi

测试 Elixir/Phoenix 服务模块

转载 作者:行者123 更新时间:2023-11-28 21:03:56 24 4
gpt4 key购买 nike

我一直在使用 Elixir/Phoenix 第三方模块。 (用于从第三方服务获取一些数据的模块)其中一个模块如下所示:

module TwitterService do
@twitter_url "https://api.twitter.com/1.1"

def fetch_tweets(user) do
# The actual code to fetch tweets
HTTPoison.get(@twitter_url)
|> process_response
end

def process_response({:ok, resp}) do
{:ok, Poison.decode! resp}
end

def process_response(_fail), do: {:ok, []}
end

在我的问题中,实际数据并不重要。所以现在,我对如何动态配置 @twitter_url 感兴趣测试中的模块变量,以使某些测试故意失败。例如:

module TwitterServiceTest
test "Module returns {:ok, []} when Twitter API isn't available"
# I'd like this to be possible ( coming from the world of Rails )
TwitterService.configure(:twitter_url, "new_value") # This line isn't possible
# Now the TwiterService shouldn't get anything from the url
tweets = TwitterService.fetch_tweets("test")
assert {:ok, []} = tweets
end
end

我怎样才能做到这一点?注意:我知道我可以使用 :configs配置@twiter_url分别在devtest环境,但我也希望能够测试来自 Twitter API 的真实响应,这将更改整个测试环境的 URL。
我想出的解决方案之一是

def fetch_tweets(user, opts \\ []) do
_fetch_tweets(user, opts[:fail_on_test] || false)
end

defp _fetch_tweets(user, [fail_on_test: true]) do
# Fails
end

defp _fetch_tweets(user, [fail_on_test: false]) do
# Normal fetching
end

但这看起来很老套和愚蠢,必须有更好的解决方案。

最佳答案

正如何塞在 Mocks And Explicit Contracts 中所建议的那样,最好的方法可能是使用依赖注入(inject):

module TwitterService do
@twitter_url "https://api.twitter.com/1.1"

def fetch_tweets(user, service_url \\ @twitter_url) do
# The actual code to fetch tweets
service_url
|> HTTPoison.get()
|> process_response
end

...
end

现在在测试中,您只需在必要时注入(inject)另一个依赖项:

# to test against real service
fetch_tweets(user)

# to test against mocked service
fetch_tweets(user, SOME_MOCK_URL)

这种方法也将使将来插入不同的服务变得更加容易。处理器的实现不应该依赖于它的底层服务,假设服务遵循一些契约(在这种特殊情况下用给定 url 的 json 响应。)

关于测试 Elixir/Phoenix 服务模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47846334/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com