Rspec:没有路线匹配{:action =>“show”,:controller =>“posts”,:id => nil}

时间:2012-11-30 13:17:23

标签: ruby-on-rails rspec tdd

我正在尝试使用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的帖子,否则就不会正确地将帖子保存到测试数据库中。我该如何解决?我是否正确地采用了正确的方法,或者是否有更好的方法来创建测试帖/测试页面?

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

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

应用程序/视图/帖/ show.html.erb:

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

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

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

3 个答案:

答案 0 :(得分:2)

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

尝试:

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

答案 1 :(得分:1)

好的,好像你的新动作和创建动作都是空的?尝试

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

的新视图

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

答案 2 :(得分:1)

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

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