我正在运行一个访问路径并在该页面上创建新会话的rspec测试。但是,即使我已经明确说明visit conversations_path
,我也无法理解为什么我会收到以下错误。在错误消息中写入的link_to语句可以在我的根路径中找到。
当我从根路径中删除link_to代码时,测试通过。
conversation_spec.rb
describe "Conversation" do
let!(:user) { FactoryGirl.create(:user) }
let!(:other_user) { FactoryGirl.create(:friend) }
before do
login_as(user, :scope => :user)
end
describe 'index' do
before do
visit conversations_path
end
it 'can be reached successfully' do
expect(page.status_code).to eq(200)
end
it "create a new conversation", **js: true** do
visit conversations_path
expect(current_path).to eq(conversations_path)
click_on "Compose"
expect(page).to have_css('.new_message_head')
end
end
失败:
1) Conversation index create a new conversation
Failure/Error: <h4><%= link_to featured_article.title, article_path(featured_article) %></h4>
ActionView::Template::Error:
undefined method `title' for nil:NilClass
答案 0 :(得分:0)
显示的具体错误是因为featured_article
为零,很可能是因为您没有为测试创建任何文章。至于为什么它会走向根路径而不是对话,如果没有看到会话控制器和/或test.log
的相关部分,就不可能肯定地说。但是,我确实有2个猜测发生了什么。
会话路径需要文章存在,因此它知道要显示的内容,并且您没有在测试数据中创建任何内容,因此它将重定向到根
您正在连续两次致电访问而未验证其是否已完成。使用之前的块,您的测试可以归结为
login_as(user,:scope =&gt;:user) 访问conversations_path 访问conversations_path ...
由于visit
无法保证在返回之前等待其操作完成(驱动程序尽力而为,但并非总是可行),因此第二次访问请求可能在第一次访问返回之前发生。假设你使用的login_as
是设计/ warden测试模式版本,它通过设置中间件来设置用户登录下一个请求(并且只接收下一个请求)。然后,这将设置会话cookie,该会话cookie随响应一起返回,保持用户在该请求之外登录。如果第二个visit
在收到并处理第一个visit
的响应之前发生,则会话cookie将不会在第二个请求中设置,因此用户实际上不会登录 - 因此导致重定向到根路径。
test.log
应确切地确定原因(或者只是尝试删除额外的visit
)
单独注意:在功能测试中测试响应代码通常是一种难闻的气味,而应该关注用户可以在页面上看到的内容。此外,您永远不应将eq
匹配器与current_path
一起使用,因为在使用支持JS的驱动程序和动态页面时,它可能导致不稳定的测试。相反,您应该使用Capybara提供的have_current_path
匹配器 - expect(page).to have_current_path(conversations_path)