我正在尝试使用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>
答案 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