至于您关于“如何使其更清晰”的第一个问题,我们可以从不使用模拟开始。
当您不能依赖辅助对象的可预测行为时,模拟对象很有用,辅助对象不重要但必须存在于您的测试用例中。使用模拟对象的典型示例是数据库查询、网络使用、文件 i/o。您不希望您的测试因为您的计算机丢失网络连接或数据库不可用而失败。
您从中获得的生成代码rails g scaffold
不是最佳的。生成的代码以使所有测试通过的方式生成,为此它使用模拟对象。我不知道他们为什么这样做,我认为更好的默认设置是测试失败,因此您实际上需要做一些事情来让它们通过。
我会删除生成的模拟并执行以下操作:
#spec/controllers/weather_controller_spec.rb
describe "POST create" do
describe "with valid params" do
it "assigns a newly created weather as @weather" do
post :create, :weather => {'location' => 'ORD', 'temp'=>'35', 'sample_time'=>'2011-02-04T20:00-0500'}
assigns(:weather).should be_valid
end
it "should redirect you to the weather show page" do
post :create, :weather => {'location' => 'ORD', 'temp'=>'35', 'sample_time'=>'2011-02-04T20:00-0500'}
response.should redirect_to(weather_path(assigns[:weather]))
end
end
describe "without valid params" do
it "should notify that a location is required" do
post :create, :weather => {'temp'=>'35', 'sample_time'=>'2011-02-04T20:00-0500'}
flash[:notice].should == 'Location is required.'
assigns(:weather).should_not be_valid
end
it "should notify that a temperature is required" do
post :create, :weather => {'location' => 'ORD', 'sample_time'=>'2011-02-04T20:00-0500'}
flash[:notice].should == 'A temperature is required.'
assigns(:weather).should_not be_valid
end
it "should notify that a sample time is required" do
post :create, :weather => {'location' => 'ORD', 'temp'=>'35'}
flash[:notice].should == 'A sample time is required.'
assigns(:weather).should_not be_valid
end
end
end
请注意,我们没有使用模拟对象,因此代码简化为使用一些参数进行 POST 调用并验证该对象是否有效。由于必须在模型文件中编写验证规则,并且您没有使用模拟对象,因此您可以确定正在进行实际验证。
使用自动生成的模拟文件,您根本不需要做任何事情,测试将永远通过。这是一个坏主意,也是不好的做法。
另请注意,您应该编写更多测试来处理无效或缺少参数的情况。再一次,通过这样做,assigns(:weather).should_not be_valid
您正在验证您的验证是否正在完成他们的工作。
每次调用时都编写参数字典post :create
是重复的、脆弱的和丑陋的。你应该学习如何使用夹具。例如,与工厂女孩
#spec/factories.rb
Factory.define :weather_valid do |f|
f.location "ORD"
f.temp "35"
f.sample_time "2011-02-04T20:00-0500"
end
#spec/controllers/weather_controller_spec.rb
describe "POST create" do
describe "with valid params" do
it "assigns a newly created weather as @weather" do
post :create, :weather => Factory.build(:weather_valid).attributes
assigns(:weather).should be_valid
end
it "should redirect you to the weather show page" do
post :create, :weather => Factory.build(:weather_valid).attributes
response.should redirect_to(weather_path(assigns[:weather]))
end
end
...
这为您提供了可重用且更具可读性的代码。