坚持:
' undefined method `post' for #<Class:0x000001058c0f68> (NoMethodError)'
关于测试控制器create
操作。
我正在使用Rails 4,rpsec和Factory Girl
控制器:
def create
@post = Post.new(post_params)
@post.user_id = current_user.id
if @post.save
flash[:success] = "Yay! Post created!"
redirect_to root_path
else
# flash[:error] = @post.errors.full_messages
render 'new'
end
end
测试:
describe '#create' do
post 'create', FactoryGirl.attributes_for(:post, user: @user)
response.should be_successful
end
答案 0 :(得分:5)
我认为可以在post
方法块中访问it
方法:
describe 'create' do
it 'should be successful' do
post :create, FactoryGirl.attributes_for(:post, user: @user)
response.should be_success
end
end
BTW我认为您需要测试重定向,而不是success
状态。
答案 1 :(得分:2)
对于偏离主题感到抱歉,但我只是想给你一些建议。
考虑关注best practices并使用RSpec的expect语法而不是应该。在这里阅读更多关于为什么语法不好的想法:http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
这就是我重写你的例子的方式:
describe 'create' do
it 'responds with 201' do
post :create, attributes_for(:post, user: @user)
expect(response.status).to eq(201)
end
end
在示例中,我使用FactoryGirl的短语法方法attributes_for
而不是FactoryGirl.attributes_for
,它节省了几个字节。以下是如何使用简短方法(在spec / test_helper.rb中):
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
我正在测试状态代码201,Rails默认会为成功的创建操作返回(重定向应该是3xx)。这使测试更加具体。
希望对编写更好的规格有任何帮助。
答案 2 :(得分:0)
问题来自于post
语句中应使用it
的事实。我通常会像这样测试我的控制器:
describe 'POST "create"' do
let(:user) { User.new }
let(:params) { FactoryGirl.attributes_for(:post, user: user) }
let(:action) { post :create, params }
let!(:post) { Post.new }
before do
Post.should_receive(:new).and_return(post)
end
context 'on success' do
before do
post.should_receive(:save).and_return(true)
end
it 'renders success' do
action
expect(response).to be_success
end
it 'redirects' do
action
expect(response).to be_redirected
end
it 'sets flash message' do
action
expect(flash[:success]).to_not be_empty
end
end
context 'on failure' do
before do
post.should_receive(:save).and_return(false)
end
it 'renders new' do
action
expect(response).to render_template(:new)
end
end
end