我有一个Foo模型,创建时需要:name 。
我正在编写一个规范来测试验证
it 'should not create an invalid Foo' do
fill_in "Name", :with=>""
# an error message will be displayed when this button is clicked
click_button "Create Foo"
end
如何确认页面上是否显示错误消息?
我试过page.errors.should have_key(:name)
但这不对。
我想我可以做page.should have_content("Name can't be blank")
但我宁愿避免将我的集成测试与内容强烈耦合
答案 0 :(得分:12)
如果您在单元测试级别正确测试验证,则可以轻松地为所需的错误消息添加另一个测试:
describe Foo do
describe "validations" do
describe "name" do
before { @foo = FactoryGirl.build(:foo) } # or Foo.new if you aren't using FactoryGirl
context "when blank" do
before { @foo.name = "" }
it "is invalid" do
@foo.should_not be_valid
end
it "adds the correct error message" do
@foo.valid?
@foo.errors.messages[:name].should include("Name cannot be blank")
end
end # positive test case omitted for brevity
end
end
end
这样,您已经隔离了错误生成并复制到模型,并且可靠地进行了测试,这允许您实现某种全局错误显示(例如,使用flash[:error],而无需测试在视图级别明确显示每条错误消息。
答案 1 :(得分:6)
你说你正在编写一个规范来测试验证,但是我看到你用“fill_in”测试了水豚(或类似的)
相反,我强烈建议您编写单元测试来测试模型。
规格/模型/ your_model_spec.rb
require 'spec_helper'
describe YourModel do
it "should not allow a blank name" do
subject.name = ""
subject.should_not be_valid
subject.should have(1).error_on(:name)
end
end
这样,你就是在隔离测试 - 只测试你需要测试的内容,而不是控制器是否正常工作,或是视图,甚至是通过闪存循环。
这样,您的测试快速,耐用且隔离。
答案 2 :(得分:1)
你的it
块说'不应该创建一个无效的Foo',如果你正在测试它真的是对模型Foo进行单元测试而不是集成测试。
但是,如果您正在测试页面上的SPECIFIC错误消息,那么您需要检查内容。为了使测试更少耦合,您可以检查特定的html元素。例如,我的错误显示在flash消息中。我通过查找名为error
或alert
的类的div来检查它们。我忽略了实际的消息,只是检查以确保出现某种错误。