Тест Rspec, если метод экземпляра вызывает метод объекта

Я пытаюсь использовать метод class_double, описанный здесь: https://relishapp.com/rspec/rspec-mocks/docs/verifying-doubles/using-a-class-double

Вот мой код:

search.rb

class Search < ActiveRecord::Base
  def find_events
    events = Event.find_by_dates(beginning_date, end_date)
  end
end

event.rb

class Event < ActiveRecord::Base
  scope :find_by_dates, ->(starting_date , ending_date) { where('(date(start_datetime) >= ? AND date(end_datetime) <= ?)', starting_date.to_date, ending_date.to_date)}
end

search_spec.rb

  let(:march1) {DateTime.parse('1st March 2014')}
  let(:march3) {DateTime.parse('3rd March 2014')}
  let(:march_search) {create(:search, beginning_date: march1, end_date: march3)}
  let(:mar1_event) {create(:event,
                       start_datetime: DateTime.parse('1st March 2014 04:00:00 PM'),
                       end_datetime: DateTime.parse('1st March 2014 06:00:00 PM'))}

  let(:mar2_event) {create(:event,
                       start_datetime: DateTime.parse('2nd March 2014 04:00:00 PM'),
                       end_datetime: DateTime.parse('2nd March 2014 06:00:00 PM'))}

  let(:mar1_to_3_event) {create(:event,
                            start_datetime: DateTime.parse('1st March 2014 04:00:00 PM'),
                            end_datetime: DateTime.parse('3rd March 2014 06:00:00 PM'))}
  let(:march_search) {create(:search, beginning_date: march1, end_date: march3)}


describe 'find_events method' do
  it 'should call Event.find_by_dates' do
  event = class_double("Event").as_stubbed_const(:transfer_nested_constants => true)
  expect(event).to receive(:find_by_dates).with(march1, march3)
  march_search.find_events
end
it 'should return events within a date range' do
  events = march_search.find_events
  expect(events).to include(mar1_event, mar2_event, mar1_to_3_event)
end

it 'it should not return events outside of the date range' do
  events = sept_search.find_events
  expect(events).to_not include(mar1_event, mar2_event, mar1_to_3_event)
end

Пока проблем нет, пока я не хочу проверить, не найдено ли результатов, и вернуть строку

def find_events
  events = Event.find_by_dates(beginning_date, end_date)
  if events.empty?
    return "SORRY NO RESULTS FOUND"
  end
end

Тогда я получаю следующие ошибки

Неудачи:

 1) Search find_events method it should not return events outside of the date range
 Failure/Error: expect(events).to_not include(mar1_event, mar2_event, mar1_to_3_event)
 TypeError:
   no implicit conversion of Event into String
 # ./spec/models/search_spec.rb:93:in `block (3 levels) in <top (required)>'

 2) Search find_events method should call Event.find_by_dates
 Failure/Error: march_search.find_events
 NoMethodError:
   undefined method `empty?' for nil:NilClass
 # ./app/models/search.rb:41:in `find_events'
 # ./spec/models/search_spec.rb:84:in `block (3 levels) in <top (required)>'

 3) Search find_events method should return events within a date range
 Failure/Error: expect(events).to include(mar1_event, mar2_event, mar1_to_3_event)
 TypeError:
   no implicit conversion of Event into String
 # ./spec/models/search_spec.rb:88:in `block (3 levels) in <top (required)>'

У меня есть Event.find_by_dates, чтобы увидеть, был ли он нулевым, но получил следующую ошибку: неопределенный метод `include?' для ноля: NilClass

I really need to check if an empty ActiveRelation object is returned to stop the search from continuing. Can anyone tell me how to test for empty and not empty search results?

Спасибо!

1 ответ

Решение

Тест не то место. Проверьте, что возвращает Event.find_by_dates в классе Event.

Все, что вас интересует для find_events в классе Search, - возвращает ли он коллекцию событий или строку.

Так что вы просто заглушаете find_by_dates на Event, чтобы вернуть либо что-то пустое, либо нет.

так что вы хотите эквивалент Event.any_instance.stub(:find_by_dates).and_return('')

PS, не забудьте расстегнуть его после теста.:(

Другие вопросы по тегам