简体   繁体   中英

How to cleanly stub out REST client when in test environment

I have a basic model like the following

class MyModel
    def initialize(attrs)   
        @attrs = attrs
        @rest_client = Some::REST::Client.new 
    end

    def do_a_rest_call(some_str)
      @rest_client.create_thing(some_str)
    end
end

For testing purposes, I don't want @rest_client to make remote calls. Instead, in a test environment, I just want to make sure that @rest_client gets called with a specific some_str when it goes through certain branches of code.

In an ideal world, I'd have an assertion similar to:

expect(my_model_instance).to.receive(do_a_rest_call).with(some_str) where in the test I will pass some_str to make sure it's the right one.

What's the best way to do this using RSpec 3.8 and Rails 5.2.2?

A solution that should work without any additional gems:

let(:rest_client_double) { instance_double(Some::REST::Client, create_thing: response) }

it 'sends get request to the RestClient' do
  allow(Some::REST::Client).to receive(:new).and_return(rest_client_double)

  MyModel.new(attrs).do_a_rest_call(some_str)

  expect(rest_client_duble).to have_received(:create_thing).with(some_str).once
end

Basically, you are creating a double for REST client. Then, you make sure that when calling Some::REST::Client.new the double will be used (instead of real REST client instance).

Finally, you call a method on your model and check if double received given message.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM