Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to generate an instance_spy for Gitlab::Client #197

Closed
jblackman opened this issue May 5, 2016 · 1 comment
Closed

Unable to generate an instance_spy for Gitlab::Client #197

jblackman opened this issue May 5, 2016 · 1 comment

Comments

@jblackman
Copy link

Here's an interesting problem. For my project unit tests I'm doubling the Gitlab::Client. Here is a stripped-down example:

require 'gitlab'

describe 'Creating an instance_spy on the client' do
  let(:gitlab_client) { instance_spy ::Gitlab::Client, get_file: 'foo' }

  before :each do
    allow(::Gitlab).to receive(:client).and_return(gitlab_client)
  end

  it 'ought to work' do
    client = Gitlab.client(endpoint: 'foo')
  end
end

This fails in an interesting manner:

Creating an instance_spy on the client
  ought to work (FAILED - 1)

Failures:

  1) Creating an instance_spy on the client ought to work
     Failure/Error: raise Error::MissingCredentials.new("Please set an endpoint to API") unless @endpoint

     Gitlab::Error::MissingCredentials:
       Please set an endpoint to API
     # ./lib/gitlab/request.rb:90:in `set_request_defaults'
     # ./lib/gitlab/api.rb:16:in `initialize'
     # ./lib/gitlab.rb:18:in `new'
     # ./lib/gitlab.rb:18:in `client'
     # ./lib/gitlab.rb:23:in `method_missing'
     # ./spy_spec.rb:4:in `block (2 levels) in <top (required)>'
     # ./spy_spec.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.00164 seconds (files took 0.17132 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spy_spec.rb:10 # Creating an instance_spy on the client ought to work

Looking into the source (I've tried this against both release 3.6.1 and master), I think I know what the problem is: in order for rspec to validate the stubbed method, it must first see if the class responds to the method. At that point, it hits either Gitlab.respond_to? or Gitlab.respond_to_missing?, depending on the gem version. This create a client object with no options, which fails because endpoint is not specified.

I want to stub the client, but in doing so it creates the client. Catch22!

Anyway, if I stub the method that does the validation, I get past this problem, but it seems like a bit of a hack to have to work around it like that (and not intuitive to the next person who comes along):

require 'gitlab'

describe 'Creating an instance_spy on the client' do
  let(:gitlab_client) { instance_spy ::Gitlab::Client, get_file: 'foo' }

  before :each do
    allow_any_instance_of(::Gitlab::Client).to receive(:set_request_defaults).and_return(nil)
    allow(::Gitlab).to receive(:client).and_return(gitlab_client)
  end

  it 'runs very nicely, thank you' do
    client = Gitlab.client(endpoint: 'foo')
    expect(client.get_file('a','b','c')).to eq 'foo'
  end
end

Any ideas? Should I be doing this a different way?

@asedge
Copy link
Collaborator

asedge commented Jul 6, 2017

Sorry man, I looked a this a while back but could not figure out a different way.

@asedge asedge closed this as completed Jul 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants