ruby-on-rails Ruby on Rails教程:Micropost控制器测试错误

w8biq8rn  于 2023-04-08  发布在  Ruby
关注(0)|答案(1)|浏览(154)

当我测试Microposts控制器时,它显示了以下内容:
第一个错误:

Failure:
MicropostsControllerTest#test_should_create_micropost 
"Micropost.count" didn't change by 1.
Expected: 3
  Actual: 2

第二个错误:

Failure:
MicropostsControllerTest#test_should_update_micropost 
Expected response to be a <3XX: redirect>, but was a <422: Unprocessable Entity>

微柱控制器:

class MicropostsController < ApplicationController
      before_action :set_micropost, only: %i[ show edit update destroy ]
    
      # GET /microposts or /microposts.json
      def index
        @microposts = Micropost.all
      end
    
      # GET /microposts/1 or /microposts/1.json
      def show
      end
    
      # GET /microposts/new
      def new
        @micropost = Micropost.new
      end
    
      # GET /microposts/1/edit
      def edit
      end
    
      # POST /microposts or /microposts.json
      def create
        @micropost = Micropost.new(micropost_params)
    
        respond_to do |format|
          if @micropost.save
            format.html { redirect_to micropost_url(@micropost), notice: "Micropost was successfully created." }
            format.json { render :show, status: :created, location: @micropost }
          else
            format.html { render :new, status: :unprocessable_entity }
            format.json { render json: @micropost.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # PATCH/PUT /microposts/1 or /microposts/1.json
      def update
        respond_to do |format|
          if @micropost.update(micropost_params)
            format.html { redirect_to micropost_url(@micropost), notice: "Micropost was successfully updated." }
            format.json { render :show, status: :ok, location: @micropost }
          else
            format.html { render :edit, status: :unprocessable_entity }
            format.json { render json: @micropost.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # DELETE /microposts/1 or /microposts/1.json
      def destroy
        @micropost.destroy
    
        respond_to do |format|
          format.html { redirect_to microposts_url, notice: "Micropost was successfully destroyed." }
          format.json { head :no_content }
        end
      end
    
      private
        # Use callbacks to share common setup or constraints between actions.
        def set_micropost
          @micropost = Micropost.find(params[:id])
        end
    
        # Only allow a list of trusted parameters through.
        def micropost_params
          params.require(:micropost).permit(:content, :user_id)
        end
    end



User Controller:

    class UsersController < ApplicationController
      before_action :set_user, only: %i[ show edit update destroy ]
    
      # GET /users or /users.json
      def index
        @users = User.all
      end
    
      # GET /users/1 or /users/1.json
      def show
      end
    
      # GET /users/new
      def new
        @user = User.new
      end
    
      # GET /users/1/edit
      def edit
      end
    
      # POST /users or /users.json
      def create
        @user = User.new(user_params)
    
        respond_to do |format|
          if @user.save
            format.html { redirect_to user_url(@user), notice: "User was successfully created." }
            format.json { render :show, status: :created, location: @user }
          else
            format.html { render :new, status: :unprocessable_entity }
            format.json { render json: @user.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # PATCH/PUT /users/1 or /users/1.json
      def update
        respond_to do |format|
          if @user.update(user_params)
            format.html { redirect_to user_url(@user), notice: "User was successfully updated." }
            format.json { render :show, status: :ok, location: @user }
          else
            format.html { render :edit, status: :unprocessable_entity }
            format.json { render json: @user.errors, status: :unprocessable_entity }
          end
        end
      end
    
      # DELETE /users/1 or /users/1.json
      def destroy
        @user.destroy
    
        respond_to do |format|
          format.html { redirect_to users_url, notice: "User was successfully destroyed." }
          format.json { head :no_content }
        end
      end
    
      #show micropost for the user
      def show
        @user = User.find(params[:id])
        @micropost = @user.microposts.first
      end
    
      private
        # Use callbacks to share common setup or constraints between actions.
        def set_user
          @user = User.find(params[:id])
        end
    
        # Only allow a list of trusted parameters through.
        def user_params
          params.require(:user).permit(:name, :email)
        end
    end

Models:

    class Micropost < ApplicationRecord
        belongs_to :user
        validates :content, length: {maximum: 140},
            presence: true
    end

    class User < ApplicationRecord
        has_many :microposts
        validates :name, presence: true
        validates :email, presence: true
    end

Micropost controller test:

require "test_helper"

class MicropostsControllerTest < ActionDispatch::IntegrationTest
  setup do
    @micropost = microposts(:one)
  end

  test "should get index" do
    get microposts_url
    assert_response :success
  end

  test "should get new" do
    get new_micropost_url
    assert_response :success
  end

  test "should create micropost" do
    assert_difference("Micropost.count") do
      post microposts_url, params: { micropost: { content: @micropost.content, user_id: @micropost.user_id } }
    end

    assert_redirected_to micropost_url(Micropost.last)
  end

  test "should show micropost" do
    get micropost_url(@micropost)
    assert_response :success
  end

  test "should get edit" do
    get edit_micropost_url(@micropost)
    assert_response :success
  end

  test "should update micropost" do
    patch micropost_url(@micropost), params: { micropost: { content: @micropost.content, user_id: @micropost.user_id } }
    assert_redirected_to micropost_url(@micropost)
  end

  test "should destroy micropost" do
    assert_difference("Micropost.count", -1) do
      delete micropost_url(@micropost)
    end

    assert_redirected_to microposts_url
  end
end

如何修复这些错误?
在添加这些之后,@micropost.update!:

def update
    respond_to do |format|
      if @micropost.update!(micropost_params)
        format.html { redirect_to micropost_url(@micropost), notice: "Micropost was successfully updated." }
        format.json { render :show, status: :ok, location: @micropost }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @micropost.errors, status: :unprocessable_entity }
      end
    end
  end

错误显示:错误:

MicropostsControllerTest#test_should_update_micropost:
ActiveRecord::RecordInvalid: Validation failed: User must exist
    app/controllers/microposts_controller.rb:40:in `block in update'
    app/controllers/microposts_controller.rb:39:in `update'
    test/controllers/microposts_controller_test.rb:37:in `block in <class:MicropostsControllerTest>'

Failure:
MicropostsControllerTest#test_should_create_micropost [/mnt/c/code/toy_application/test/controllers/microposts_controller_test.rb:19]:
"Micropost.count" didn't change by 1.
Expected: 3
  Actual: 2

当我尝试应用程序时,我仍然可以成功添加新用户并更新帖子。

shyt4zoc

shyt4zoc1#

在Rails fixture中,要引用关联中的模型,可以在fixture中使用标签,也可以使用在fixture中指定的id
例如,使用fixture的标签,我们可以定义users.yml如下:

one:
  name: foo
  email: foo@one.me

two:
  name: bar
  email: bar@two.me

microposts.yml可以使用带有标签的users模型:

one:
  content: MyText
  user: one

two:
  content: MyText
  user: two

或者,使用id需要在users.yml中指定id,如下所示:

one:
  id: 1
  name: foo
  email: foo@one.me

two:
  id: 2
  name: bar
  email: bar@two.me

microposts.yml

one:
  content: MyText
  user_id: 1

two:
  content: MyText
  user_id: 2

official documentation提供了关于这方面的优秀信息,尤其是Label references for associations (belongs_to, has_one, has_many)部分。

相关问题