Oauth模型关注测试覆盖存根

我试图找出在这个课程上达到100%测试覆盖率的最佳方法。 我概述了我的完整规范,我希望有人可以指出我正确的方向。 我的假设是将Oauth2请求存根,但我似乎无法做到这一点。

我正在使用Rails 4。

在此处输入图像描述

规格

RSpec.describe 'AppOmniAuthentication', type: :concern do let(:klass) { User } let(:user) { create(:user) } let(:user_oauth_json_response) do unfiltered_oauth_packet = load_json_fixture('app_omni_authentication_spec') unfiltered_oauth_packet['provider'] = unfiltered_oauth_packet['provider'].to_sym unfiltered_oauth_packet['uid'] = unfiltered_oauth_packet['uid'].to_i unfiltered_oauth_packet end before do OmniAuth.config.test_mode = true OmniAuth.config.mock_auth[:app] = OmniAuth::AuthHash.new( user_oauth_json_response, credentials: { token: ENV['APP_CLIENT_ID'], secret: ENV['APP_CLIENT_SECRET'] } ) end describe '#from_omniauth' do let(:app_oauth) { OmniAuth.config.mock_auth[:app] } it 'returns varying oauth related data for Bigcartel OAuth response' do data = klass.from_omniauth(app_oauth) expect(data[:provider]).to eq(user_oauth_json_response['provider'].to_s) expect(data[:uid]).to eq(user_oauth_json_response['uid'].to_s) expect(data[:email]).to eq(user_oauth_json_response['info']['email']) expect(data[:customer_ids]).to eq(user_oauth_json_response['extra']['raw_info']['customer_ids']) end end describe '#refresh_access_token!' do it 'false if OAuth2 Fails' do allow(user).to receive(:access_token) { true } allow(user).to receive(:refresh_access_token!) { false } allow(user).to receive(:result).and_raise(OAuth2::Error) expect(user.refresh_access_token!).to be_falsey end it 'false if refresh fails' do allow(user).to receive(:access_token) { true } allow(user).to receive(:refresh_access_token!) { false } expect(user.refresh_token!).to be_falsey end it 'true if new token' do allow(user).to receive(:access_token) { true } allow(user).to receive(:refresh_access_token!) { true } expect(user.refresh_token!).to be_truthy end it 'true when refreshed' do auth_token = OpenStruct.new(token: FFaker::Lorem.characters(50), refresh_token: FFaker::Lorem.characters(50), expires_at: 5.days.from_now) allow(user).to receive_message_chain('access_token.refresh!') { auth_token } expect(user.refresh_access_token!).to be_truthy end end describe '#refresh_token!' do it 'false if no access token' do allow(user).to receive(:access_token) { false } expect(user.refresh_token!).to be_falsey end it 'false if refresh fails' do allow(user).to receive(:access_token) { true } allow(user).to receive(:refresh_access_token!) { false } expect(user.refresh_token!).to be_falsey end it 'true if new token is saved' do allow(user).to receive(:access_token) { true } allow(user).to receive(:refresh_access_token!) { true } expect(user.refresh_token!).to be_truthy end end describe '#token expired?' do it 'true if valid' do expect(user.token_expired?).to be_falsey end it 'false if expired' do user.token_expires_at = 10.days.ago expect(user.token_expired?).to be_truthy end end end 

UPDATE

我将当前的规格改为:

 it 'false if OAuth2 Fails' do allow(OAuth2::AccessToken).to receive(:access_token) { Class.new } allow(OAuth2::AccessToken).to receive_message_chain('access_token.refresh!') { raise OAuth2::Error.new('ERROR') } binding.pry end 

但是,现在我收到以下错误:

 WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request.. 

看起来关键是这里的第二行:

 def refresh_access_token! result = access_token.refresh! store_token(result) save rescue OAuth2::Error false end 

您的所有其他测试存根access_token 。 如果您有一个称为真实方法的测试,它将覆盖access_tokenclientstrategysettings缺少的行。

现在strategysettingsclient都非常无聊:前两个基本上只是常量。 并且client只是通过初始化它不会做任何事情。 所以打电话给那些应该没什么大不了的。 只留下access_token 。 您可以看到初始化OAuth2::AccessToken ,其代码在Github上 。 初始化程序也很无聊。 它只是保存输入以便以后使用。

所以我会把它refresh! 方法:一次返回有效的刷新令牌,一次提出OAuth2::Error 。 您可以使用expect_any_instance_of来执行此操作。 如果这让你感到不安,你也可以使用stub :new本身,让它返回你自己的假对象:

 o = expect(OAuth2::AccessToken).to receive(:new) { Object.new } expect(o).to receive(:refresh!) { raise OAuth2::Error.new("something here") } 

看起来构造OAuth2::Error可能有点麻烦,因为它需要一个请求对象 ,但我没有看到任何太复杂的东西,只是凌乱。

这应该给你100%的覆盖率!

(代表问题作者发布解决方案)

现在已经解决了。

  describe '#refresh_access_token!' do it 'false if OAuth2 Fails' do response = OpenStruct.new(error: 'ERROR') allow(OAuth2::AccessToken).to receive_message_chain(:new, :refresh!) { raise OAuth2::Error.new(response) } expect(user.refresh_token!).to be_falsey end it 'true if new token' do allow(OAuth2::AccessToken).to receive_message_chain(:new, :refresh!) { @auth_token } expect(user.refresh_token!).to be_truthy end end 

存根令牌看起来像:

 @auth_token = OpenStruct.new(token: FFaker::Lorem.characters(50), refresh_token: FFaker::Lorem.characters(50), expires_at: 5.days.from_now) 

在研究了Paul Jungwirth发布的概念之后,对gem中的方法进行存根阻止了Webmock警报的触发(按预期),我可以正确触发加注。 加注也必须与gem的响应设置相匹配。