【问题标题】:Rspec test failing: creating new record rather than using existing oneRspec 测试失败:创建新记录而不是使用现有记录
【发布时间】:2013-07-01 12:06:33
【问题描述】:

我有以下代码:

describe "when visiting roll call with no notes" do
  before do
    login_as_sensei
    @dojo = FactoryGirl.create(:dojo, name: "Melbourne")
    @time = FactoryGirl.create(:times, dojo: @dojo)
    @roll = FactoryGirl.create(:roll_call)
    visit time_roll_calls_path("melbourne", "14-2-2013", "1000")
  end

  specify { @roll.notes.should be_blank }
  it { should_not have_content("This is a note!") }

  describe "and filling in note information correctly" do
    before do
      fill_in "roll_call[notes]", with: "This is a note!"
      click_button "Add Notes"
    end

    it { should have_content("This is a note!") } # 'it' refers to the page
    specify { RollCall.last.notes.should_not be_blank }
    specify { @roll.notes.should_not be_blank }
    specify { @roll.reload.notes.should_not be_blank }
  end
end

据我所知,最后所有 4 个测试都应该通过,但是只有前 2 个可以通过:

it { should have_content("This is a note!") }
specify { RollCall.last.notes.should_not be_blank }

最后 2 个返回以下错误:

1) RollCalls when visiting roll call with no notes and filling in note information correctly 
 Failure/Error: specify { @roll.notes.should_not be_blank }
   expected blank? to return false, got true
 # ./spec/features/roll_calls_spec.rb:241:in `block (4 levels) in <top (required)>'

2) RollCalls when visiting roll call with no notes and filling in note information correctly 
 Failure/Error: specify { @roll.reload.notes.should_not be_blank }
   expected blank? to return false, got true
 # ./spec/features/roll_calls_spec.rb:242:in `block (4 levels) in <top (required)>'

这是 rspec 应该如何工作还是我做错了什么?

【问题讨论】:

  • 你试过@roll.notes.reload吗? (即重新加载 notes 集合,而不是 RollCall 对象?)
  • @DylanMarkow 刚刚尝试了你的建议,得到了undefined method 'reload' for nil:NilClass,所以基本上是同样的错误。

标签: ruby-on-rails rspec ruby-on-rails-3.2 rspec-rails


【解决方案1】:

您在这里混合接受规范和请求规范。 @roll 不会在您执行 capybara 请求时被修改(通过 fill_in 等)。

验收规范测试响应的内容。请求规范对给定请求的记录进行测试操作。您可以考虑像这样拆分测试:

# Acceptance test
describe "when visiting roll call with no notes" do
  before do
    login_as_sensei
    @dojo = FactoryGirl.create(:dojo, name: "Melbourne")
    @time = FactoryGirl.create(:times, dojo: @dojo)
    @roll = FactoryGirl.create(:roll_call)
    visit time_roll_calls_path("melbourne", "14-2-2013", "1000")
  end

  it { should_not have_content("This is a note!") }

  describe "and filling in note information correctly" do
    before do
      fill_in "roll_call[notes]", with: "This is a note!"
      click_button "Add Notes"
    end

    it { should have_content("This is a note!") } # 'it' refers to the page
  end
end

# Request specs
describe RollCallsController do
  describe "#action" do
    before do
      login_as_sensei
      @roll = FactoryGirl.create(:roll_call)

    end

    it "should initially be blank" do
      get "/some/path", :id => @roll.id
    end

    it "should add a note" do
      post "/roll_calls/#{@roll.id}/notes/add", roll_call: {notes: "New note"}
      @roll.reload.notes.should_not be_blank
      @roll.reload.notes[0].note.should == "New note"
    end
  end
end

【讨论】:

  • 感谢克里斯的解释。在这种情况下只坚持验收测试是否有意义,或者编写两个测试是常见的做法?
  • 这取决于您要测试的内容,真的。我倾向于使用请求测试来测试单个控制器操作的效果,并使用验收测试来测试一系列操作。
猜你喜欢
  • 2023-01-12
  • 2012-07-25
  • 2021-03-30
  • 2011-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-23
  • 2023-04-01
相关资源
最近更新 更多