Rspec + FactoryGirl:为什么 'let' 语句的放置会影响变量的创建和测试中的使用
Rspec + FactoryGirl : Why does the placement of 'let' statements affect creation of variable and usage in test
我很难理解 Rspec 创建用于测试的数据的逻辑。
我有几种情况,除了第一种情况外,所有情况都会导致错误。错误意味着当我打印页面时,记录未在 HTML 中呈现,这意味着未创建变量。
这是我的工厂:
文章:
FactoryGirl.define do
factory :article do
title "First test article"
summary "Summary of first article"
description "This is the first test article."
user
end
end
评论:
FactoryGirl.define do
factory :comment do
sequence(:content) { |n| "comment text #{n}" }
article
user
end
end
spec/features/article_spec.rb
1) 在 rspec 测试中显式创建注释变量。
require 'rails_helper'
describe "Comments on article" do
let!(:user) { FactoryGirl.create(:user) }
let!(:article) { FactoryGirl.create(:article) }
let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
before do
login_as(user, :scope => :user)
visit article_path(article)
end
describe 'edit', js: true do
let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
it 'a comment can be edited through ajax' do
print page.html
find("a[href = '/articles/#{article.friendly_id}/comments/#{comment.id}/edit']").click
expect(page).to have_css('#comment-content', text: "Some comments")
within('.card-block') do
fill_in 'comment[content]', with: "Edited comments"
click_on "Save"
end
expect(page).to have_css('#comment-content', text: "Edited comments")
end
end
结束
2) 将 let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
替换为以下内容:
let!(:comment) { FactoryGirl.create(:comment) }
3) 放置让!第一个 'it' 块之前的语句
describe 'edit', js: true do
let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
it 'a comment can be edited through ajax' do
print page.html
find("a[href = '/articles/#{article.friendly_id}/comments/#{comment.id}/edit']").click
expect(page).to have_css('#comment-content', text: "Some comments")
within('.card-block') do
fill_in 'comment[content]', with: "Edited comments"
click_on "Save"
end
expect(page).to have_css('#comment-content', text: "Edited comments")
end
end
更新:
我发现设置测试 data/variables 对我这个 Rspec 新手来说是一个很大的 pain/stumbling 障碍。以下是我发现的一些对我有帮助的参考资料:
1) When is using instance variables more advantageous than using let()?
2) https://www.ombulabs.com/blog/rails/rspec/ruby/let-vs-instance.html
let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
let!(:comment) { FactoryGirl.create(:comment) }
这些不会创建相同的评论 - 在第二种情况下,创建的评论不会与用户或文章相关联(而是与新用户和新文章相关联)。
您是在检查变量并发现它为零,还是只是按照您在页面上看到的内容进行操作?如果您要查看页面上的内容,是否可能只向您显示与给定 article/user 相关的评论?
至于另一个问题,before 块在 describe 中创建的注释变量之前执行 - 因此在您导航到页面之前注释不存在。
我很难理解 Rspec 创建用于测试的数据的逻辑。
我有几种情况,除了第一种情况外,所有情况都会导致错误。错误意味着当我打印页面时,记录未在 HTML 中呈现,这意味着未创建变量。
这是我的工厂:
文章:
FactoryGirl.define do
factory :article do
title "First test article"
summary "Summary of first article"
description "This is the first test article."
user
end
end
评论:
FactoryGirl.define do
factory :comment do
sequence(:content) { |n| "comment text #{n}" }
article
user
end
end
spec/features/article_spec.rb
1) 在 rspec 测试中显式创建注释变量。
require 'rails_helper'
describe "Comments on article" do
let!(:user) { FactoryGirl.create(:user) }
let!(:article) { FactoryGirl.create(:article) }
let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
before do
login_as(user, :scope => :user)
visit article_path(article)
end
describe 'edit', js: true do
let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
it 'a comment can be edited through ajax' do
print page.html
find("a[href = '/articles/#{article.friendly_id}/comments/#{comment.id}/edit']").click
expect(page).to have_css('#comment-content', text: "Some comments")
within('.card-block') do
fill_in 'comment[content]', with: "Edited comments"
click_on "Save"
end
expect(page).to have_css('#comment-content', text: "Edited comments")
end
end
结束
2) 将 let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
替换为以下内容:
let!(:comment) { FactoryGirl.create(:comment) }
3) 放置让!第一个 'it' 块之前的语句
describe 'edit', js: true do
let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
it 'a comment can be edited through ajax' do
print page.html
find("a[href = '/articles/#{article.friendly_id}/comments/#{comment.id}/edit']").click
expect(page).to have_css('#comment-content', text: "Some comments")
within('.card-block') do
fill_in 'comment[content]', with: "Edited comments"
click_on "Save"
end
expect(page).to have_css('#comment-content', text: "Edited comments")
end
end
更新:
我发现设置测试 data/variables 对我这个 Rspec 新手来说是一个很大的 pain/stumbling 障碍。以下是我发现的一些对我有帮助的参考资料:
1) When is using instance variables more advantageous than using let()?
2) https://www.ombulabs.com/blog/rails/rspec/ruby/let-vs-instance.html
let!(:comment) {Comment.create(content:"Some comments", article_id: article.id, user_id: user.id)}
let!(:comment) { FactoryGirl.create(:comment) }
这些不会创建相同的评论 - 在第二种情况下,创建的评论不会与用户或文章相关联(而是与新用户和新文章相关联)。
您是在检查变量并发现它为零,还是只是按照您在页面上看到的内容进行操作?如果您要查看页面上的内容,是否可能只向您显示与给定 article/user 相关的评论?
至于另一个问题,before 块在 describe 中创建的注释变量之前执行 - 因此在您导航到页面之前注释不存在。