Как чисто отключить REST-клиент в тестовой среде

#ruby-on-rails #unit-testing #testing #rspec

#ruby-on-rails #модульное тестирование #тестирование #rspec

Вопрос:

У меня есть базовая модель, подобная следующей

 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
  

В целях тестирования я не хочу, чтобы @rest_client выполнял удаленные вызовы. Вместо этого в тестовой среде я просто хочу убедиться, что он @rest_client вызывается с определенным some_str значением, когда проходит через определенные ветви кода.

В идеальном мире у меня было бы утверждение, подобное:

expect(my_model_instance).to.receive(do_a_rest_call).with(some_str) где в тесте я передам some_str, чтобы убедиться, что он правильный.

Каков наилучший способ сделать это, используя RSpec 3.8 и Rails 5.2.2?

Комментарии:

1. Я не знаю о «лучшем способе». (Как вы определяете «лучший»?) Но я использую webmock , и это кажется мне не таким уж ужасным способом.

Ответ №1:

Решение, которое должно работать без каких-либо дополнительных элементов:

 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
  

По сути, вы создаете double для REST-клиента.
Затем вы убедитесь, что при вызове Some::REST::Client.new будет использоваться double (вместо реального экземпляра REST-клиента).

Наконец, вы вызываете метод в своей модели и проверяете, получил ли double данное сообщение.

Комментарии:

1. какое значение в аргументе create_thing?

2. В первой строке? Там вы определяете имя метода и ответ, который должен быть возвращен. Итак, если вы вызовете, Some::REST::Client.new.create_thing вы получите response .