我对测试并不陌生。我为自己感到自豪,有97% - 100%的测试覆盖率。事实上,95%以下的任何东西都很差(但这不是主题)。我有以下rails控制器:
module Api
module Internal
class TwitterController < Api::V1::BaseController
# Returns you 5 tweets with tons of information.
#
# We want 5 specific tweets with the hash of #AisisWriter.
def fetch_aisis_writer_tweets
tweet_array = [];
tweet = twitter_client.search("#AisisWriter").take(5).each do |tweet|
tweet_array.push(tweet)
end
render json: tweet_array
end
private
# Create a twitter client connection.
def twitter_client
client = Twitter::REST::Client.new do |config|
config.consumer_key = ENV['CONSUMER_KEY']
config.consumer_secret = ENV['CONSUMER_SECRET_KEY']
config.access_token = ENV['ACCESS_TOKEN']
config.access_token_secret = ENV['ACCESS_TOKEN_SECRET']
end
end
end
end
end
看到最新情况,这是非常基本的。现在我可以编写rspec测试来说出这个动作,I expect json['bla']['text'] to eql bla
。
但是有几个问题。为了有效地测试这个,您需要twitter API凭据。这就是我的代码与我希望启动并运行的另一项服务的结合。
事实上,我的控制器基本上与推特耦合。
所以 - 我的问题是,不必嘲笑网络服务或api电话(我已经看到了一些关于此的博客文章,对于这段代码,我觉得他们已经过度杀戮) - 怎么会你测试一下吗?
有些人建议录像机。有关测试API调用的任何想法都是这样的吗?
答案 0 :(得分:1)
我发现VCR是这类测试的绝佳工具 - 您不需要对外部服务返回的内容进行大量控制,因为您不需要有很多案例需要测试。您只是想根据服务是否已启动来消除测试片状,并且您希望确保每次都获得完全相同的假响应。我根本不会说VCR太过分了,使用非常简单 - 只需将测试包装在use_cassette
块中,运行测试,VCR记录服务的实际响应并将其用作当时的模拟回应。
我会说&#34;录音带&#34; VCR用于存储模拟响应的是相当复杂的YAML,并且它们不具有超级可读/易编辑性。如果您希望能够轻松地操作返回的数据,以便您可以测试多个代码路径,并轻松阅读它,以便您的模拟数据可以作为代码的文档,我会调查更像是HttpMock。
当然,另一个选择是将调用外部服务的私有方法存根,并让它直接返回模拟数据。通常我会避免这种情况,因此您可以重构您的私有方法并仍然被覆盖,但在某些情况下,私有方法很简单并且不太可能发生变化,这可能是一种选择,并且将其删除会显着清洁测试。