我是Rspec
和Capybara
的新手。我得到的错误是从主页访问图库导航
Failure/Error: visit root_path
NoMethodError:undefined method 'testimonials' for nil:NilClass
我尝试了两种不同的方式来定义规范中的变量。我已经添加了这两个,以便我可以获得有关我做错的反馈。
class WelcomeController < ApplicationController
def index
@event = Event.last
@event.testimonials.first ? @latest_testimonial = @event.testimonials.first.id : @latest_testimonial = nil
end
end
feature 'Navigation from homepage' do
before :each do
visit root_path
find('#nav-menu').find('h1').click #opens up navigation bar
end
scenario 'Visit Gallery' do
find('#nav-gallery').find('.no_bar').click
let(:event) {Event.last} #1st attempt at solving Rspec error.
let(:event) {mock_model(Event, id: 3, name: "Jack & Jill", date: "2004-06-10", created_at: "2014-03-10 02:57:45", updated_at: "2014-03-10 02:57:45")} #2nd attempt at solving Rspec error.
controller.stub(:event)
expect(page).to have_css 'img.photos'
end
end
答案 0 :(得分:2)
另一个答案是正确的 - 这里的内容基本上是相同的内容(或者可能只是通过解释你已经知道的事情来解释)。
您的测试所做的第一件事就是执行访问before
的{{1}}块,可能会调用root_path
上的index
操作。方法执行的第一件事是调用WelcomeController
,它返回Event.last
,因为您的测试数据库为空,因此没有最后一条记录要返回。然后,当您在nil
上致电testimonials
时,您会收到错误,因为@event
为@event
。
要解决此问题,您需要在导航到nil
并调用Event
操作之前在数据库中创建root_path
记录。一种方法是在index
:
visit root_path
这将在数据库中创建一条记录,因此Event.create(name: "Jack & Jill" [...])
将返回一些内容。
您还可以删除Event.last
语句和let
语句。现在这些都是不必要的(无论如何还有其他问题)。这应该足以使代码至少运行。
在实践中,你不会发现创建像我这里所展示的可持续方法的记录 - 工厂(使用像FactoryGirl这样的工具)或模拟/存根进入的地方然后使用controller.stub
在let
块中仅定义一次这些项目,并且仍然将创建它们所消耗的开销限制在实际使用它们的后续测试中。
无论如何,重点是在开始触发假定存在这些对象的控制器操作之前,需要完成对象(以及记录,如果需要)的设置。
答案 1 :(得分:1)
Event.last
正在返回nil。
执行此操作的典型(也是最简单)方法是在尝试访问网站之前在测试中创建一个事件,然后您的控制器将使用它。功能规范应该包含最少量的模拟和存根 - 它们代表了与系统交互的真实用户。
您的存根未被使用(事实上它们本身就是错误)。事实证明,您的错误即使在设置之前就会出现。