我正在chapter 9进行Hartl的练习,并参与了为要求登录用户编写集成测试的部分。
我注意到代码清单9.17(i)使用了
get :edit, id: @user
而代码9.14(ii)使用:
get edit_user_path(@user)
区别是什么?为了测试登录用户如果没有登录则被重定向到主页,后者工作,而前者抛出错误。
从概念上讲,上面的两个陈述看起来是一样的,i)调用控制器动作,而ii)路由到资源
是吗?
答案 0 :(得分:2)
实际上,这两个代码在概念上是等价的。
他们通过在GET
中通过users/edit.html.erb
操作向edit
发出Userscontroller
请求来做同样的事情。
但是,您测试上述行为的背景不同。
代码
get :edit, id: @user
是在测试控制器(UsersController
)的上下文中。因此,您只需要指定操作("编辑"在这种情况下)以及必要的参数(" id"在这种情况下)。
get edit_user_path(@user)
是模拟用户浏览应用程序的环境,您可以通过集成测试来完成。在这里,您需要准确了解路由路径,因为可能涉及不同的控制器。也就是说,调用动作的上下文不限于一个特定的控制器。 例如,在Listing 8.40中,我们有一个模拟用户注销的集成测试:
test "login with valid information followed by logout" do
get login_path
post login_path, session: { email: @user.email, password: 'password' }
assert is_logged_in?
assert_redirected_to @user
follow_redirect!
assert_template 'users/show'
assert_select "a[href=?]", login_path, count: 0
assert_select "a[href=?]", logout_path
assert_select "a[href=?]", user_path(@user)
delete logout_path
assert_not is_logged_in?
assert_redirected_to root_url
# Simulate a user clicking logout in a second window.
delete logout_path
follow_redirect!
assert_select "a[href=?]", login_path
assert_select "a[href=?]", logout_path, count: 0
assert_select "a[href=?]", user_path(@user), count: 0
end
在此集成测试中,涉及两个控制器:UsersController
和SessionsController
。
具体做法是:
user_path(@user)
中的assert_select "a[href=?]",
user_path(@user)
与show
中的UsersController
行为有关。 login_path
在get login_path
中调用了new
个动作
SessionsController
。
login_path
在post login_path, session: { email: @user.email,
password: 'password' }
中调用了create
个动作
SessionsController
。
login_path
中的assert_select "a[href=?]", login_path
即将发布
new
中的SessionsController
操作。logout_path
中的assert_select "a[href=?]", logout_path
是
关于destroy
中的SessionsController
操作。这在集成测试中是可能的,因为我们在调用某些操作时不限于特定的控制器。
这也解释了为什么你提供的第一个代码
get :edit, id: @user
在集成测试中抛出错误。
它没有在调用edit
动作的控制器中指定。 (可能是edit
或AccountActivationsController
中的PasswordResetsController
操作,例如)
另外,你提出的观点
i)调用控制器动作,而ii)路由到资源
很重要。
控制器测试纯粹是关于通过发出相当于"低级"或"机器级",命令来测试控制器。也就是说,我们将特定的HTTP请求(在您的情况下为PATCH
)直接提交给控制器操作(在您的案例中为edit
),而不用担心模拟用户浏览您的应用程序(即用户实际点击链接& #34;编辑个人资料"),您可以使用更多"高级"集成测试。