这是我的示例测试块
it 'should redirect to account portfolio items page if user is creative and its first visit is false and sign in count is 1' do
@creative.first_visit = false
@creative.sign_in_count = 1
@creative.save!
sign_in @creative
get :index
@creative.reload
@creative.first_visit.should eql(true)
response.should redirect_to account_portfolio_items_path
end
如果我不使用保存和重新加载测试将失败。你知道它为什么会发生,我该如何处理?
这是我的测试宝石。
group :test do
gem "rspec-rails"
gem "factory_girl"
gem "database_cleaner"
gem 'webrat', '0.7.1'
gem 'shoulda'
end
答案 0 :(得分:0)
您应该使用assigns
从RSpec中的控制器访问实例变量,而不是使用重新加载。有关编写规范的理想方式的更多详细信息,请参阅Better Specs。
答案 1 :(得分:0)
听起来不错。通常,您的控制器操作会执行数据库提取以获取其数据。在您的测试中,您可能会按摩数据,但如果您不先保存,那么您的控制器将无法获得您期望的数据。想象一下这个小场景:
# in your test ...
user = User.new
get :index
assigns(:users).should eq [user]
# in your controller ...
def index
@users = User.all
end
此测试将失败,因为测试中的user
从未保存,因此当控制器执行User.all
时,它无法找到用户。
与测试类似,当您更新属性并且控制器获取记录时,它不知道您的更改,因为它们尚未保存到数据库中。您肯定需要保存@creative
模型。
对于重新加载,当您从数据库中获取模型或创建一个全新的模型时,它的属性存储在内存中的实例中。当您将first_visit
属性更改为false时,您在内存中更改了它。保存实例时,它已应用于数据库。当您调用index
操作时,它会更新所提取的Creative
实例,使first_visit
为true
。但是,在您的测试中,您仍在使用内存中的对象,它将其作为false
。 reload
强制从数据库中重新获取对象,这样您就可以看到它的当前和更新属性。
如果您的控制器设置了一个实例变量(如@creative
),那么重新加载的替代方法是通过assigns()
帮助器访问它,如下所示:
get :index
assigns(:creative).first_visit.should eql(true)
这就是说实例变量@creative
(控制器设置)将first_visit
属性设置为true
。