Тест 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, не забудьте расстегнуть его после теста.:(