Reputation: 6096
I'm trying to create a very simple blog using Rails, for my own education. It's the first Rails app I've ever created other than from working through tutorials.
So far I just have a very simple model where each post has only a string for the title and a string for the content. Everything works fine and as expected in the browser, but I can't get the tests to pass.
Here's are the failing test in my Rspec code (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
This gives me the same error message for all 3:
Failure/Error: before { visit post_path(@post) }
ActionController::RoutingError:
No route matches {:action=>"show", :controller=>"posts", :id=>nil}
So it seems to me the problem is that the line @post = Post.create(...) is creating a post without an id, or else it's not saving the post to the test database correctly. How do I fix this? And am I going about this the right way in the first place, or is there a better way I could be creating the test post/testing the page?
This is only a problem in testing. When I view a single post in the browser everything looks fine. The Posts controller is: (I have edited this since posting the original question)
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
And here's the Post model in its entirety:
class Post < ActiveRecord::Base
attr_accessible :content, :title
validates :content, presence: true
validates :title, presence: true
end
config/routes:
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>
Upvotes: 1
Views: 5600
Reputation: 1359
Your instance variable needs to go into the before block. (the test is trying to goto /posts/:id/show and params[:id] in this case is nil as @post hasnt been created)
try:
before do
@post = Post.create(title: "The title", content: "The content")
visit post_path(@post)
end
Upvotes: 2
Reputation: 1325
Do you need to put your 'before' stuff outside the test? This works for me:
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
Upvotes: 1
Reputation: 15374
Ok so it seems your new and create actions are empty?? Try
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
and then your view for new needs to have a form_for @post
You cant create a new post without this and only when this is successful your posts will e assigned ids
Upvotes: 1