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 中创建的注释变量之前执行 - 因此在您导航到页面之前注释不存在。