Ruby on Rails教程第3版,第9章:对users_edit_test.rb

时间:2015-08-22 05:57:08

标签: ruby-on-rails ruby ruby-on-rails-3

我一直收到三个错误,我不知道为什么。我尽可能地遵循教程,并且我已经通过第9章了解错误,但我还没有看到任何错误。正在运行bundle exec rake test。我得到以下三个错误:

FAIL["test_unsuccessful_edit", UsersEditTest, 2015-08-22 09:09:06 +0900]
 test_unsuccessful_edit#UsersEditTest (1440202146.96s)
        expecting <"users/edit"> but rendering with <[]>
        test/integration/users_edit_test.rb:12:in `block in <class:UsersEditTest>'

 FAIL["test_successful_edit", UsersEditTest, 2015-08-22 09:09:06 +0900]
 test_successful_edit#UsersEditTest (1440202146.97s)
        expecting <"users/edit"> but rendering with <[]>
        test/integration/users_edit_test.rb:25:in `block in <class:UsersEditTest>'

 FAIL["test_successful_edit_with_friendly_forwarding", UsersEditTest, 2015-08-22 09:09:07 +0900]
 test_successful_edit_with_friendly_forwarding#UsersEditTest (1440202147.07s)
        Expected response to be a redirect to <http://www.example.com/users/762146111/edit> but was a redirect to <http://www.example.com/>.
        Expected "http://www.example.com/users/762146111/edit" to be === "http://www.example.com/".
        test/integration/users_edit_test.rb:43:in `block in <class:UsersEditTest>'

如您所见,我的所有错误都可以在test / integration / users_edit_test中找到。我的两个测试以同样的方式失败,并显示以下消息:expecting <"users/edit"> but rendering with <[]>。第12行和第25行具有相同的代码:

assert_template 'users/edit'

第43行具有以下代码:

assert_redirected_to edit_user_path(@user)

我有一个带有链接的_header.html.erb文件,该链接应该转到用户的编辑页面,但它只是重定向到索引。我有一个文件app / views / users / edit.html.erb,所以我不知道为什么它没有显示出来。以下是设置链接的代码:

<li><%= link_to "Settings", edit_user_path(current_user) %></li>

这是我的users_controller.rb文件的代码。我怀疑问题是我的correct_user方法没有像它应该的那样开火。 (顺便说一句,我已尝试在&#34;编辑&#34;方法中注释掉代码,但问题仍然存在。)

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
  before_action :correct_user, only: [:edit, :update]
  before_action :admin_user, only: :destroy

  def index
    @users = User.paginate(page: params[:page])
  end

  def show
    @user = User.find(params[:id])
    # debugger
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
        log_in @user
        flash[:success] = "Welcome to the Sample App!"
          redirect_to @user
    else
        render 'new'
    end
  end

  def edit
  #  @user = User.find(params[:id])
  end

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

  def destroy
    User.find(params[:id].destroy)
    flash[:success] = "User deleted"
    redirect_to users_url
  end

  private

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

    def logged_in_user
      unless logged_in?
        store_location
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end

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

    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end
end

在app / helpers / sesions_helper.rb中我有两种方法,current_usercurrent_user?

def current_user?(user)
  user == current_user
end

def current_user
    if(user_id = session[:user_id])
        @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
        user = User.find_by(id: user_id)
        if user && user.authenticated?(cookies[:remember_token])
            log_in user
            @current_user = user
        end
    end
end

这是config / routes文件:

root 'static_pages#home'
  get 'help' => 'static_pages#help'
  get 'about' => 'static_pages#about'
  get 'contact' => 'static_pages#contact'
  get 'signup' => 'users#new'
  get 'login' => 'sessions#new'
  post 'login' => 'sessions#create'
  delete 'logout' => 'sessions#destroy'
  resources :users

我怀疑我的问题的答案非常容易,但我不知道出了什么问题。这是users_edit_test.rb文件

require 'test_helper'

class UsersEditTest < ActionDispatch::IntegrationTest
  def setup
    @user = users(:michael)
  end

  test "unsuccessful edit" do
#    log_in_as(@user)
    get edit_user_path(@user)
    log_in_as(@user)
    assert_template 'users/edit'
    patch user_path(@user), user: { name: '',
                                    email: 'foo@invalid',
                                    password: 'foo',
                                    password_confirmation: 'bar' }
    assert_template 'users/edit'
  end


  test "successful edit" do
#    log_in_as(@user)
    get edit_user_path(@user)
    log_in_as(@user)
    assert_template 'users/edit'
    name = "Foo Bar"
    email = "foo@bar.com"
    patch user_path(@user), user: { name: name,
                                    email: email,
                                    password: '',
                                    password_confirmation: '' }
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal @user.name, name
    assert_equal @user.email, email
  end

  test "successful edit with friendly forwarding" do
    log_in_as(@user)
    get edit_user_path(@user)
#    log_in_as(@user)
    assert_redirected_to edit_user_path(@user)
    name = "Foo Bar"
    email = "foo@bar.com"
    patch user_path(@user), user: { name: name,
                    email: email,
                    password: 'foobar',
                    password_confirmation: 'foobar' }
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal @user.name, name
    assert_equal @user.email, email
  end
end

7 个答案:

答案 0 :(得分:4)

虽然您没有在此处上传users_edit_test.rb文件,但实际上我从您提到的书中读到了chapter 9,然后还从其github repo获取了源代码。

所以,我在本地运行了与你的相同的测试(bundle exec rake test test/integration/users_edit_test.rb)并且它正常通过。没有测试失败。但是,我发现,如果log_in_as(@user)测试中缺少test "unsuccessful edit",那么它会失败并显示您在此处发布的完全相同的错误消息。而且,这是有道理的,因为,如果您没有log_in_as(@user)即已登录的用户,则它无法呈现该用户的编辑页面,从而出现此错误:

expecting <"users/edit"> but rendering with <[]>

所以,我很确定你在教程中输入时错过了那部分。

以下是users_edit_test.rb文件的完整工作版本(所有测试都已通过)

require 'test_helper'

class UsersEditTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end

  test "unsuccessful edit" do
    log_in_as(@user)
    get edit_user_path(@user)
    assert_template 'users/edit'
    patch user_path(@user), user: { name: "",
                                    email: "user@invalid",
                                    password:              "foo",
                                    password_confirmation: "bar" }
    assert_template 'users/edit'
  end

  test "successful edit with friendly forwarding" do
    get edit_user_path(@user)
    log_in_as(@user)
    assert_redirected_to edit_user_path(@user)
    name  = "Foo Bar"
    email = "foo@bar.com"
    patch user_path(@user), user: { name:  name,
                                    email: email,
                                    password:              "",
                                    password_confirmation: "" }
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name,  @user.name
    assert_equal email, @user.email
  end
end

只需复制此内容并用此替换当前文件的内容即可。然后,所有测试都将通过。

答案 1 :(得分:1)

让您的 users.yml 定义明确,并且不会错误。我有一个错字,并得到了同样的错误。

错误(注意电子邮件中的上方E)

michael:
  name: michael Example
  email: michael@Example.com
  password_digest: <%= User.digest('password') %>

定义明确

michael:
  name: michael Example
  email: michael@example.com
  password_digest: <%= User.digest('password') %>

答案 2 :(得分:0)

我现在正在完成这个教程,并且测试通过得很好,所以我将我的测试与你的测试进行比较,你需要进行以下更改:

  1. If Left$(ActiveDocument.Tables(1).Rows(1).Cells(3).Range.Text, 1) = "1" Then successful test中,将unsuccessful test放在log_in_as(@user)之前。
  2. get edit_user_path(@user)中,恰恰相反:在{/ strong> successful test with friendly forwarding之后放置log_in_as(@user)
  3. 在您的users_controller.rb文件中,检查您的私有get edit_user_path(@user)方法:

    correct_user

    应该是

    redirect_to(root_url) unless @user == current_user?(@user)
    
  4. 进行这些更改并重新运行测试套件应该会使测试通过。

答案 3 :(得分:0)

我遵循相同的教程,但我得到了同样的错误:

  expecting <"users/edit"> but rendering with <[]>

我只是通过此块的位置切换来解决它:

  test "unsuccesful edit" do
    log_in_as(@user)
    get edit_user_path(@user)
    assert_template 'users/edit'
    patch user_path(@user), user: { name: "", 
                                    email: "invalid@invalid",
                                    password: "foo",
                                    password_confirmation: "bar" }
    assert_template 'users/edit'
  end

和这一个:

  test "successful edit" do
    log_in_as(@user)
    get edit_user_path(@user)
    assert_template 'users/edit'
    name = "Name"
    email = "valid@valid.com"
    patch user_path(@user), user: { name: name, 
                                    email: email,
                                    password: "",
                                    password_confirmation: "" }
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name, @user.name
    assert_equal email, @user.email
  end

实际上现在它按照我放置两个块的任何顺序工作..我知道它没有任何意义但也许它与Cloud9上的一些奇怪的剪切和粘贴行为相关联(云 - 基于IDE的作者建议使用的。)

你是怎么解决这个问题的呢?

答案 4 :(得分:0)

我也正在完成本教程。我有一些类似的问题。

如果我理解正确<[]>表示测试浏览器尚未遵循的重定向。我会在失败的断言之前放一个debugger并从那里检查情况。在我的情况下,原因是遗忘的follow_redirect!assert_template而不是assert_redirected_to

答案 5 :(得分:0)

其实我遇到了同样的问题。 在我的情况下,我发现我在灯具 user.yml 中更改了用户的密码。

几个小时后,我发现之间必须有强烈的对齐:

  1. user.yml
  2. test_helper.rb2。
  3. 数据库(存储摘要的位置)

答案 6 :(得分:0)

如果有人仍然有此错误,我可以通过将def设置中的用户从users.yml更改为另一个用户来解决。