Oauth Model Concern Test Coverage Stubs

天涯浪子 提交于 2019-12-02 11:32:46

It looks like the key is the second line here:

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

All your other tests stub access_token. If you had a test that called the real method, it would cover the missing lines in access_token, client, strategy, and settings.

Now strategy,settings, and client are all pretty boring: the first two are essentially just constants. And client doesn't do anything just by initializing it. So calling those should be no big deal. That leaves just access_token. You can see that that initializes an OAuth2::AccessToken, whose code is on Github. The initializer is also pretty boring. It just saves the inputs to use later.

So I would stub its refresh! method: once to return a valid-looking refresh token, and once to raise an OAuth2::Error. You can use expect_any_instance_of to do that. If that makes you uneasy you could also stub :new itself, and have it return your own fake object:

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

It looks like it might be a little bit of a nuisance to construct an OAuth2::Error since it takes a request object, but I don't see anything too complicated there, just messy.

That should give you 100% coverage!

(Posted solution on behalf of the question author).

This is now solved.

  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

The stubbed token looks like:

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

After researching the concept that Paul Jungwirth posted, stubbing the methods in the gem prevented the Webmock alert from firing (as intended) and I could trigger the raise correctly. The raise had to match the gem's response setup as well.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!