我正在开发一个从外部REST API(来自Facebook,Twitter或Instagram等社交网络)获取数据的项目。
我不确定我所做的是对还是错所以我需要一些指导。我不知道当人们创建依赖于外部数据的应用程序(REST API或爬行数据)时,他们会使用它进行TDD。
我的问题是:我正在尝试对调用外部REST API的方法进行TDD测试。这是对还是错?
例如:
我有这样的代码:
API_VERSION = "v2.5"
FIELD_PAGE_GRAPH = %w(id name picture{url} likes cover is_community_page category link website has_added_app
talking_about_count username founded phone mission location is_published description can_post checkins company_overview
general_info parking hours payment_options access_token
)
FIELD_STREAM_GRAPH = %w(id message story comments.summary(true) likes.summary(true).limit(500) from to link shares created_time
updated_time type is_published attachments scheduled_publish_time application
)
def self.get_stat_facebook(page_id,access_token=nil)
graph = Koala::Facebook::API.new(access_token)
graph.get_objects(page_id.to_s,{:fields => FIELD_PAGE_GRAPH}, {:api_version => API_VERSION})
end
def self.get_feed_facebook(page_id,access_token=nil, options = {})
options = options.with_indifferent_access
retry_time = 0
begin
graph = Koala::Facebook::API.new(access_token)
params = {:fields => FIELD_STREAM_GRAPH, :limit => 25}
params.merge!({:since => options[:_since].to_i}) if options[:_since].present?
params.merge!({:until => options[:_until].to_i}) if options[:_until].present?
results = []
loop do
graph_response = graph.get_object(page_id.to_s+"/feed", params, {:api_version => API_VERSION})
break if graph_response.blank?
results = results+graph_response
break if options[:_since].blank?
params[:until] = graph_response.sort_by!{|result| result['created_time']}.first['created_time'].to_time.to_i-1
end
rescue Koala::Facebook::ServerError
sleep 1
retry_time += 1
retry if retry_time <= 3
end
filter_owner_page(results, page_id)
end
然后我有一个像
这样的规范require 'spec_helper'
RSpec.describe SocialNetwork do
context ".get_stat_facebook" do
it "when access token is expired"
it "when access token is not expired"
it "when page id is not exist"
it "when page id is exist"
end
context ".get_feed_facebook" do
it "when access token is expired"
it "when access token is not expired"
it "when page id is not exist"
it "when page id is exist"
it "data contain id field"
it "data contain message field"
it "data contain attachment field"
end
end
答案 0 :(得分:2)
是的,它适用于测试以获得外部服务,但您可以通过几种方式将其对测试套件的影响降至最低。
我会按如下方式测试此代码:
为SocialNetwork
编写RSpec规范(单元测试)。
SocialNetwork
的其他规范中,只测试您已经测试过的调用变体的那些规范,找出考拉。很难准确地解释哪些测试应该打到Facebook以及哪些应该使用存根而不将它们放在我们面前。如果您需要更多建议,请查看它是如何发布的。
答案 1 :(得分:2)
TDD用于测试您的方法作为一个单元。来自外部的数据可以是mocked,因此您可以涵盖每个方案。像
这样的东西graph = double()
allow(graph).to receive(:get_object).and_return(data)
-
我也会改变
context ".get_stat_facebook" do
代表
describe ".get_stat_facebook" do
并使用上下文来描述您要测试的方案。它将提高可读性。
更多:大方法难以测试,因此您可以将#get_feed_facebook
分成小部分(如构建参数,循环等)以提高可测试性。
答案 2 :(得分:0)
听起来我想要实现的是功能/验收测试,而不是单元测试。我个人认为在单元测试中,你应该隔离你的单元(方法)并尝试注入所需的依赖项(mock)并评估函数的输出(期望和断言)。
在你的情况下,我认为你可以期待你使用的sdk方法,例如,你有以下方法:
def do_something_with_facebook
@graph = Koala::Facebook::API.new(oauth_access_token)
end
在这种情况下,我会编写一个测试,检查您的方法是否如下所示调用Koala::Facebook::API
。
def test_method_calls_koalla
grape = mock
Koala::Facebook
.expects(:new)
.returns(grape)
method = do_something_with_facebook
end
它可能不是rspec语法,但我希望它能给你一些想法。
答案 3 :(得分:0)
你说,“我正在尝试对调用外部REST API的方法进行TDD测试。”对我来说,这是一个单元测试环(支付'测试方法'的短语)。 “这是对还是错?”,你问。绝对正确(IMO)。
我当前的项目广泛使用来自多个其他系统的外部API。我使用webmock。它给了我很多控制权,以确保请求格式正确(网址,查询,标题等),让我测试各种响应(成功,权限被拒绝,网络超时等)。而且,管理外部API版本也很容易。
对我来说,这是测试访问外部API的方法最直接,最低开销的方法。如果感兴趣的话,很高兴说出更多。