【问题标题】:Rspec: No route matches {:action=>"show", :controller=>"posts", :id=>nil}Rspec:没有路由匹配 {:action=>"show", :controller=>"posts", :id=>nil}
【发布时间】:2012-11-18 17:21:08
【问题描述】:

我正在尝试使用 Rails 创建一个非常简单的博客,用于我自己的教育。这是我创建的第一个 Rails 应用程序,而不是通过教程工作。

到目前为止,我只有一个非常简单的模型,其中每个帖子只有一个标题字符串和一个内容字符串。在浏览器中一切正常且符合预期,但我无法通过测试。

这是我的 Rspec 代码 (spec/requests/post_spec.rb) 中的失败测试:

require 'spec_helper'

describe "Posts" do

  .
  .
  .

  describe "viewing a single post" do

    @post = Post.create(title: "The title", content: "The content")

    before { visit post_path(@post) }

    it { should have_selector('title',    text: @post.title) }
    it { should have_selector('h1',       text: @post.title) }
    it { should have_selector('div.post', text: @post.content) }

  end

end

这给了我所有 3 个相同的错误消息:

Failure/Error: before { visit post_path(@post) }
     ActionController::RoutingError:
       No route matches {:action=>"show", :controller=>"posts", :id=>nil}

所以在我看来,问题在于 @post = Post.create(...) 行正在创建一个没有 id 的帖子,或者它没有正确地将帖子保存到测试数据库中。我该如何解决?我是否首先以正确的方式解决这个问题,还是有更好的方法可以创建测试帖子/测试页面?

这只是测试中的问题。当我在浏览器中查看单个帖子时,一切看起来都很好。 Posts 控制器是:(我在发布原始问题后对其进行了编辑)

class PostsController < ApplicationController
  def new
    @post = Post.new
  end

  def create
    @post = Post.new(params[:post])
    if @post.save
      redirect_to posts_path, :notice => "Post successfully created!"
    end
  end

  def index
  end

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

这是整个 Post 模型:

class Post < ActiveRecord::Base
  attr_accessible :content, :title

  validates :content, presence: true
  validates :title,   presence: true
end

配置/路由:

Blog::Application.routes.draw do
    resources :posts

    root to: 'posts#index'
end

app/views/posts/show.html.erb:

<% provide(:title, @post.title) %>

<h1><%= @post.title %></h1>

<div class="post"><%= @post.content %></div>

【问题讨论】:

  • 你能告诉我们路线吗?
  • 你有演出路线吗?
  • 刚刚编辑了问题以包含它们。
  • 好的,请您确认在创建新帖子时,您的帖子已创建吗?因为您似乎没有 id
  • 不确定您的意思。我可以在控制台中创建一个新帖子,然后在浏览器中通过 URL localhost:3000/posts/2(或任何数字)查看该帖子。我不知道如何确认在测试中创建了新帖子。

标签: ruby-on-rails rspec tdd


【解决方案1】:

您的实例变量需要进入 before 块。 (测试试图转到 /posts/:id/show 和 params[:id] 在这种情况下是 nil,因为 @post 尚未创建)

尝试:

before do
    @post = Post.create(title: "The title", content: "The content") 
    visit post_path(@post)
end

【讨论】:

    【解决方案2】:

    好吧,看来您的 new 和 create 操作是空的??试试

    def new
    @post =Post.new
    end
    
    def create
    @post = Post.new(params[:post])
    if @post.save
      redirect_to posts_path, :notice => " Post successfully created."
    end
    end
    

    然后你对新需求的看法需要有一个 form_for @post

    没有这个你不能创建一个新帖子,只有当这个成功时你的帖子才会被分配 ids

    【讨论】:

    • 好的,我将这些确切的方法添加到我的帖子控制器中,并在 app/views/posts/new.html.erb 中创建了一个非常简单的 form_for。当我在 localhost:3000/posts/new 上创建帖子时,它可以工作,我可以在(例如)localhost:3000/posts/3 上查看新创建的帖子。但测试仍然失败,并显示与以前完全相同的错误消息!
    • 看看这篇文章对你有没有用stackoverflow.com/questions/2183372/…
    【解决方案3】:

    您是否需要将“之前”的内容放在测试之外?这对我有用:

    require 'spec_helper'
    describe "Posts" do
    
      before(:each) do 
        @post = Post.create(title: "The title", content: "The content")    
      end
    
      describe "viewing a single post" do
        it "should show the post details" do
          get post_path(@post) 
          response.status.should be(200)
          # do other tests here .. 
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-22
      • 2014-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多