#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
.