0

这是我的示例测试块

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
4

2 回答 2

0

您应该使用assigns从 RSpec 中的控制器访问实例变量,而不是使用重新加载。有关编写规范的理想方式的更多详细信息,请参阅Better Specs

于 2013-06-17T13:35:48.987 回答
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_visitbe true。但是,在您的测试中,您仍在使用将其作为false. reload强制从数据库中重新获取对象,这使您可以查看它的当前和更新属性。

重新加载的替代方法是,如果您的控制器设置了一个实例变量,例如@creative,通过assigns()帮助程序访问它,如下所示:

get :index
assigns(:creative).first_visit.should eql(true)

这就是说实例变量@creative(控制器设置)将有一个first_visit属性设置为true.

于 2013-06-17T13:43:44.303 回答