Rspec测试实例方法是否调用对象方法

时间:2014-03-26 23:25:28

标签: rspec ruby-on-rails-4 guard spork

我正在尝试使用此处说明的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

我真的需要检查是否返回空的ActiveRelation对象以阻止搜索继续。谁能告诉我如何测试空的而不是空的搜索结果?

谢谢!

1 个答案:

答案 0 :(得分:1)

测试是错误的地方。测试Event.find_by_dates在Event类上返回的内容。

Search类中关于find_events的所有关注点是它是返回事件集合还是字符串。

所以你只需在Event上存根find_by_dates就可以返回空的或不是。

所以你想要相当于Event.any_instance.stub(:find_by_dates).and_return('')

PS,测试后不要忘记取消它。 :(