Rails 5 testing controller show action, missing required keys: [:id]

Kizlo kizlo Source

i'm using rails 5.1.5, and default testing library, so when i try to test my show action in posts contoller, i get an error:

Error:
PostsControllerTest#test_should_show_post:
ActionController::UrlGenerationError: No route matches
{:action=>"show",   :controller=>"posts"}, missing required keys: [:id]

here is My posts_controller_test.rb

require 'test_helper'

class PostsControllerTest < ActionDispatch::IntegrationTest

test "should get index" do
  get posts_url, params: { keywords: "" }
  assert_response :success
end

test "should show post" do
  post = posts(:post)
  get post_url, params: {id: post.id}
  assert_response :success
end

end

Here is my post fixture file posts.yml

post:
  title: testpost
  body: lorem ipsum
  user: tom

routes.rb

Rails.application.routes.draw do
  root "posts#index"
  devise_for :users
  resources :posts do
    resources :comments
  end
  resources :users, except: [:create, :new]
  resources :tags, only: [:show, :create]
end

posts_controller.rb

class PostsController < ApplicationController

  before_action :set_post, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]
  before_action :check_owner, only: [:destroy, :edit, :update]


  def index
    @posts = Post.search(params[:keywords]).uniq
  end

  def show
    #set_post
  end

  def new
    @post = Post.new
  end

  def create
    @post = Post.new(post_params)
    # link the post to user that logged in atm
    @post.user = current_user
    if @post.save
      # redirect to created post and show flash
      redirect_to @post, success: "Post successfully created !"
    else
      render :new
    end
  end

  def edit
    #set_post
    #check_owner
  end

  def update
    #set_post
    #check_owner
    if @post.update_attributes(post_params)
      # redirect to updated post and show flash
      redirect_to @post, success: "Post successfully updated !"
    else
      render :edit
    end
  end

  def destroy
    #set_post
    #check_owner
    @post.destroy
    # redirect to root and show flash
    redirect_to posts_path, success: "Post successfully deleted !"
  end


  private

    def set_post
      @post = Post.find(params[:id])
    end

    # strong params
    def post_params
      params.require(:post).permit(:title, :body, :image, :image_cache, :status, :adress, :current_tags)
    end

    def check_owner
      #check if current user is owner of the post
      redirect_to @post, alert: "You are not the owner of this post" unless current_user == @post.user || current_user.admin?
    end
end

and finally my test console

Running via Spring preloader in process 3663
Loading test environment (Rails 5.1.5)
2.4.1 :001 > User.all
User Load (0.3ms)  SELECT  "users".* FROM "users" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 1038054164, email: "[email protected]", created_at: "2018-03-13 16:49:29", updated_at: "2018-03-13   16:49:29", username: "Tomaskoz", avatar: nil, role: "user">]>
2.4.1 :002 > Post.all
Post Load (0.3ms)  SELECT  "posts".* FROM "posts" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Post id: 445279374, title: "testpost",  body: "lorem ipsum", created_at: "2018-03-13 16:49:29", updated_at: "2018-03-13 16:49:29", image: nil, user_id: 1038054164, status: true, adress:  nil>]>
2.4.1 :003 > 

My should get index test goes fine, but the second one doesn't, i've tried to solve the problem by myself for 2 days, but it's not seems to be possible, please help me thank in advance !

ruby-on-railsruby-on-rails-3ruby-on-rails-4testing

Answers

answered 3 months ago Tobias #1

You have an integration test there. Since you use the url helper you have to pass the ID into the helper.

test "should show post" do
  post = posts(:post)
  get post_url(post)
  assert_response :success
end

comments powered by Disqus