[英]Achieving 100% test coverage in Rails Oauth using Rspec stubs and mocks
[英]Oauth Model Concern Test Coverage Stubs
我正在嘗試找出達到此課程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
更新
我將當前規范更改為:
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
。 如果您有一個調用了real方法的測試,它將覆蓋access_token
, client
, strategy
和settings
缺少的行。
現在, strategy
, settings
和client
都非常無聊:前兩個本質上只是常量。 client
不僅僅通過初始化就做任何事情。 因此,打電話給那些應該沒什么大不了的。 剩下的只是access_token
。 您會看到它初始化了一個OAuth2::AccessToken
,其代碼在Github上 。 初始化程序也很無聊。 它只是保存輸入以供以后使用。
所以我會存根refresh!
方法:一次返回一個看上去有效的刷新令牌,一次返回一個OAuth2::Error
。 您可以使用expect_any_instance_of
來做到這一點。 如果那讓您感到不安,您還可以存根:new
本身,並讓它返回您自己的假對象:
o = expect(OAuth2::AccessToken).to receive(:new) { Object.new }
expect(o).to receive(:refresh!) { raise OAuth2::Error.new("something here") }
構造一個OAuth2::Error
似乎有點麻煩,因為它需要一個request對象 ,但是我看不到那里太復雜了,只是一團糟。
那應該給你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提出的概念之后,在寶石中添加方法會阻止Webmock警報觸發(如預期的那樣),我可以正確觸發加薪。 加薪也必須與寶石的響應設置相匹配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.