我的ActiveRecord模型有回调,如下所示:
before_save :sync_to_external_apis
def sync_to_external_apis
[user, assoc_user].each {|cuser|
if cuser.google_refresh
display_user = other_user(cuser.id)
api = Google.new(:user => cuser)
contact = api.sync_user(display_user)
end
}
end
我想写一个rspec测试,测试调用save!在google_refresh为true时,在此模型的实例上会导致在新的Google实例上调用sync_user。我怎么能这样做?
答案 0 :(得分:4)
it "should sync to external apis on save!" do
model = Model.new
model.expects(:sync_to_external_apis)
model.save!
end
另外,在请求 - 响应周期期间请求不可靠的资源(如互联网)是一个坏主意。我建议改为创建一个后台工作。
答案 1 :(得分:0)
通常的测试方法是确保结果符合预期。由于您在这种情况下使用的API可能会使事情变得复杂。您可能会发现使用mocha创建一个模拟对象,您可以发送API调用,这样您就可以将Google
类替换为可用于测试目的的一些东西。
更简单但更笨重的方法是使用“测试模式”开关:
def sync_to_external_apis
[ user, assoc_user ].each do |cuser|
if (Rails.env.test?)
@synced_users ||= [ ]
@synced_users << cuser
else
# ...
end
end
end
def did_sync_user?(cuser)
@synced_users and @synced_users.include?(cuser)
end
这是一种简单的方法,但它不会验证您的API调用是否正确。
答案 2 :(得分:-1)
def test_google_api_gets_called_for_user_and_accoc_user user = mock('User') # define a mock object and label it 'User' accoc_user = mock('AssocUser') # define a mock object and label it 'AssocUser' # instantiate the model you're testing with the mock objects model = Model.new(user, assoc_user) # stub out the other_user method. It will return cuser1 when the mock user is # passed in and cuser2 when the mock assoc_user is passed in cuser1 = mock('Cuser1') cuser2 = mock('Cuser2') model.expects(:other_user).with(user).returns(cuser1) model.expects(:other_user).with(assoc_user).returns(cuser2) # set the expectations on the Google API api1 - mock('GoogleApiUser1') # define a mock object and lable it 'GoogleApiUser1' api2 - mock('GoogleApiUser2') # define a mock object and lable it 'GoogleApiUser2' # call new on Google passing in the mock user and getting a mock Google api object back Google.expects(:new).with(:user => cuser1).returns(api1) api1.expects(:sync_user).with(cuser1) Google.expects(:new).with(:user => cuser2).returns(api2) api2.expects(:sync_user).with(cuser2) # now execute the code which should satisfy all the expectations above model.save! end
上面看起来似乎很复杂,但是一旦你掌握了它,它就不是了。您正在测试当您调用save时,您的模型会执行它应该执行的操作,但您没有麻烦,或者没有真正与API通信,实例化数据库记录等的时间费用。