测试在Rails控制器中创建操作

时间:2015-09-06 05:04:24

标签: ruby-on-rails wordpress rspec

测试Rails 4使用RSpec 3的应用程序在帖子#create上运行测试时会引发参数错误(0表示0)。

我的控制器:

def create
  @post = Post.new(post_params)

  respond_to do |format|
    if @post.save
      format.html  { redirect_to(@post,
                  :notice => 'Post was successfully created.') }
      format.json  { render :json => @post,
                  :status => :created, :location => @post }
    else
      format.html  { render :action => "new" }
      format.json  { render :json => @post.errors,
                  :status => :unprocessable_entity }
    end
  end
end

private

  def post_params
    params.require(:post).permit(:title, :body)
  end

我的路线:

resources :posts

我的测试:

describe 'POST posts#create' do
  it 'allows admin to create a new post' do
    sign_out user
    sign_in admin
    post :create, post: { title: 'Title', body: 'Body' }
    expect(response).to have_http_status(:success)
  end
end

问题出在控制器测试的post :create...行。我不确定它为什么运行不正常。我尝试过的解决方案:

1 post :create, post: title: 'Title', body: 'Body'

认为我的语法有问题。但是,这会引发错误。

2 post :create, { title: 'Title', body: 'Body' }

我认为帖子可能是隐含的,因为它是控制器的名称。没有骰子。

3 post :create, post:(post_params)

同样,我认为因为我已经建立了通常允许的参数,所以它们是必要的。毫不奇怪,该测试在其当前范围内没有post_params。

4 post :create, post: { admin: { title: 'Title', body: 'Body' } }

我之前读过你必须传递用户创建帖子项目。不正确。

5 post :create=> { title: 'Title', body: 'Body' }

我认为可能是发布隐式创建帖子的情况,因为那是控制器。但是,它返回参数错误。

6 post :post=> { title: 'Title', body: 'Body' }

最后,我认为我必须发布一个新帖子给出参数而不必使用创建动作。

修改 - 7 post(:create, post: { title: 'Title', body: 'Body' })

在审核了API文档(http://api.rubyonrails.org/classes/ActionController/TestCase.html)后,我认为这样可行,但它仍然是相同的参数错误。

8

describe 'POST admin#create' do
  it 'allows admin to create a new post' do
    sign_in admin
    expect{
      post :create, post: {title: 'Title', body: 'Body' }
    }.to change(Post, :count).by(1)
  end
end

我试图将expect作为一个块,认为它会拿起参数。不。

妥协解决方案

describe 'POST admin#create' do
  it 'allows admin to create a new post' do
    sign_in admin
    expect{
      Post.create({title: 'Title', body: 'Body' })
    }.to change(Post, :count).by(1)
  end
end

我认为作为控制器名称的动作的名称会使RSpec失效。所以,我只是手动创建了一个帖子。可能不是推荐的解决方案。

这些都没有奏效。我错过了什么?

错误输出

 Failure/Error: post(:create, post: { title: 'Title', body: 'Body' })
 ArgumentError:
   wrong number of arguments (2 for 0)
 # ./spec/controllers/posts_controller_spec.rb:101:in `block (3 levels) in <top (required)>'

我还取消了所有before_filters以查看是否存在问题,但是,它会出现同样的错误。

1 个答案:

答案 0 :(得分:0)

您的语法看起来正确。它看起来像这样:

describe 'POST admin#create' do
  it 'allows admin to create a new post' do
    sign_out user
    sign_in admin
    post(:create, {post: {title: 'Title', body: 'Body'}})
    expect(response).to have_http_status(:success)
  end
end

...但是parens和外部卷曲是可选的。

错误不是来自您的测试。在发布到:create期间发生错误。在:create请求期间,它来自控制器或模型中的来自