Michael Hartl的RoR教程 - 坚持第9章 - 无法通过RSpec测试

时间:2013-12-12 22:58:44

标签: ruby-on-rails ruby rspec

我是编程的绝对初学者(刚开始深入研究Ruby on Rails),这是我在StackOverflow上的第一篇文章,但我事先做了一个彻底的研究,没有一个类似问题的答案为我提供了我的解决方案问题

即,在Michael Hartl的“使用Rails学习Web开发”教程的第9.2.1节之后启动我的测试套件时,我收到了2次失败:

Failures:

1) Authentication authorization for non-signed-in users in the Users controller submitting to the update action 
 Failure/Error: before { patch user_path(user) }
 ActionController::ParameterMissing:
   param not found: user
 # ./app/controllers/users_controller.rb:39:in `user_params'
 # ./app/controllers/users_controller.rb:28:in `update'
 # ./spec/requests/authentication_pages_spec.rb:63:in `block (6 levels) in <top (required)>'

2) Authentication authorization for non-signed-in users in the Users controller visiting the edit page 
 Failure/Error: it { should have_title('Sign in') }
   expected #has_title?("Sign in") to return true, got false
 # ./spec/requests/authentication_pages_spec.rb:59:in `block (6 levels) in <top (required)>'

Finished in 2.35 seconds
70 examples, 2 failures

Failed examples:

rspec ./spec/requests/authentication_pages_spec.rb:64 # Authentication authorization for non-signed-in users in the Users controller submitting to the update action 
rspec ./spec/requests/authentication_pages_spec.rb:59 # Authentication authorization for non-signed-in users in the Users controller visiting the edit page 

这是/spec/requests/authentication_pages_spec.rb:

describe "authorization" do

    describe "for non-signed-in users" do
        let(:user) { FactoryGirl.create(:user) }

        describe "in the Users controller" do

            describe "visiting the edit page" do
                before { visit edit_user_path(user) }
                it { should have_title('Sign in') }
            end

            describe "submitting to the update action" do
                before { patch user_path(user) }
                specify { expect(response).to redirect_to(signin_path) }
            end
        end
    end
end

这是我的/app/controllers/users_controller.rb:

  class UsersController < ApplicationController
  before_action :signed_in_user, only: [:edit, :update]
  before_action :correct_user,   only: [:edit, :update]

  ...

  def edit
  end

  def update
    if @user.update_attributes(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation)
  end

  # Before filters

  def signed_in_user
    redirect_to signin_url, notice: "Please sign in." unless signed_in?
  end

  def correct_user
    @user = User.find(params[:id])
    redirect_to(root_url) unless current_user?(@user)
  end
end

...并且我会在这里呈现登录页面:

/app/views/sessions/new.html.erb:

<% provide(:title, "Sign in") %>
<h1>Sign in</h1>

<div class="row">
<div class="span6 offset3">
    <%= form_for(:session, url: sessions_path) do |f| %>

    <%= f.label :email %>
    <%= f.text_field :email %>

    <%= f.label :password %>
    <%= f.password_field :password %>

    <%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
    <% end %>

    <p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>

如果需要在此添加任何其他文件,请询问,因为我不确定是否发布了所需的所有内容。第一次失败似乎与User控制器中的强参数有关,尽管我一点一点地检查了修改过的代码,但没有发现任何差异。在第二次失败的情况下,我不知道那里会出现什么问题,因为当我在浏览器中访问它时,应用程序似乎生成了正确的标题,但测试失败了。

提前感谢您为帮助我做出的任何努力。

米甲

1 个答案:

答案 0 :(得分:1)

您的第一个错误是ActionController::ParameterMissing。这是因为您的user_params方法调用了params.require(:user)。这意味着如果没有定义params [:user],它将引发异常。

当您调用patch user_path(user)时,您没有传入导致异常的用户参数。但是,你永远不应该user_params,因为signed_in_user之前应该运行并将你重定向到另一个页面。

这导致我推测您的测试用户已经登录。您可能已在sign_in的早期部分进行了authentication_pages_spec.rb调用。你呢?如果是这样,请将其移到context "when signed in"块内,并且规范应该通过。

同样,如果您的测试用户实际登录了,您就不会看到登录链接 - 所以修复它也可以解决您的第二个错误。