我正在运行以下测试
test "create if user1 or user2" do
[@user1.id, @user2.id, @user3.id].each do |user_id|
assert_difference('Message.count') do
post :create, {:message => 'blah blah'}, {:user_id => user_id}
end
end
end
此代码按预期执行3个循环,但仅发布第一个用户(在本例中为user1)。 因此,当user3尝试发布时,我不会失败(因为它实际上仍然是用user1发布的)
当我更改我的应用程序控制器时
def current_user
@user ||= User.find(session[:user_id]) if session[:user_id]
end
到
@user = User.find(session[:user_id]) if session[:user_id]
我的测试工作正常,但我不明白为什么。
我认为每个帖子应该像在网络浏览器中一样从头开始运行整个应用程序
答案 0 :(得分:0)
您的代码在没有|| =的情况下工作的原因是因为它有效地缓存了“User.find ...”结果的值。请参阅以下内容:
# Behavior of 'or equals' operator, ||=
ruby-1.9.2-p180 :001 > a = 1
=> 1
ruby-1.9.2-p180 :002 > a = 2
=> 2
ruby-1.9.2-p180 :003 > a ||= 3
=> 2
ruby-1.9.2-p180 :004 > a
=> 2
“或等于”表示“将值赋给变量,除非变量已经有值。”
答案 1 :(得分:0)
可能有助于理解即使您同时将user1,user2和user3连接到您的Web应用程序,每个用户都有一个会话,但每个会话只有一个'current_user'。
考虑到这一点,您的测试似乎没有正确更改正在使用的用户会话。相反,它只是寻找一个current_user
,它实际上并没有改变用户会话。
您需要找到一种方法来正确更改您用于发布帖子的用户会话。例如,注销并在循环开始时记录下一个用户。
答案 2 :(得分:0)
考虑到这一点的方法是每个测试等同于单个请求。如果您发出单个请求,则只需要查找一次用户,因此使用||=
方法中的current_user
进行缓存是有意义的。请求之后,将丢弃缓存的值。
单个测试不会丢弃缓存的值,因此current_user
始终返回@user1
。您需要运行多个测试,或者在测试后明确注销用户。