Rails集成测试语法 - 使用get:edit vs get edit_user_path

时间:2016-04-14 20:27:15

标签: ruby-on-rails syntax get integration-testing patch

我正在chapter 9进行Hartl的练习,并参与了为要求登录用户编写集成测试的部分。

我注意到代码清单9.17(i)使用了

get :edit, id: @user

而代码9.14(ii)使用:

get edit_user_path(@user)

区别是什么?为了测试登录用户如果没有登录则被重定向到主页,后者工作,而前者抛出错误。

从概念上讲,上面的两个陈述看起来是一样的,i)调用控制器动作,而ii)路由到资源

是吗?

1 个答案:

答案 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

在此集成测试中,涉及两个控制器:UsersControllerSessionsController

具体做法是:

    user_path(@user)中的
  • assert_select "a[href=?]", user_path(@user)show中的UsersController行为有关。
  • {li>

    login_pathget login_path中调用了new个动作 SessionsController

    {li>

    login_pathpost 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动作的控制器中指定。 (可能是editAccountActivationsController中的PasswordResetsController操作,例如)

另外,你提出的观点

  

i)调用控制器动作,而ii)路由到资源

很重要。

控制器测试纯粹是关于通过发出相当于"低级"或"机器级",命令来测试控制器。也就是说,我们将特定的HTTP请求(在您的情况下为PATCH)直接提交给控制器操作(在您的案例中为edit),而不用担心模拟用户浏览您的应用程序(即用户实际点击链接& #34;编辑个人资料"),您可以使用更多"高级"集成测试。