RSpec功能测试重定向到错误的位置

时间:2012-06-02 15:42:23

标签: testing rspec mocking bdd stub

我需要一些帮助,试图让这个测试通过,但没有运气。

describe 'PUT posts/:id' do 

  describe 'with valid attributes' do

    let(:mock_post) { mock_model('Post', title: 'hey! iam a mock!', description: 'a sexy model', location: 'everywhere') }

    login_user

    it 'should update the object and redirect to the post' do 
      Post.stub!(:find).with(mock_post.id).and_return(mock_post)

      Post.any_instance.should_receive(:update_attributes).with({"these" => "params"}).and_return(true)

      response.should redirect_to post_path(mock_post)

      put :update, id: mock_post.id, post: { these: 'params' }
    end

    it 'should have a current_user' do 
      subject.current_user.should_not be_nil
    end

  end

目前,我有类似上述测试的内容并收到以下错误:

1) PostsController PUT posts/:id with valid attributes should update the object and redirect to the post
     Failure/Error: response.should redirect_to post_path(mock_post)
       Expected response to be a <:redirect>, but was <200>
     # ./spec/controllers/posts_controller_spec.rb:200:in `block (4 levels) in <top (required)>'

PostsController:

class PostsController < ApplicationController
  load_and_authorize_resource except: [:index, :show]
  before_filter :authenticate_user!, except: [:index, :show, :tags]
  before_filter :find_post, only: [:show, :edit, :update, :suspend, :suspend_alert]

def update
  if @post.update_attributes(params[:post])
    flash[:success] = 'Cool.'
    redirect_to post_path(@post)
  else
    render :edit
  end
end

protected
  def find_post
    @post = Post.find(params[:id])
  end
end

另外,我应该如何编写render :edit部分的测试?

1 个答案:

答案 0 :(得分:2)

您的规范从不调用控制器操作。尝试添加:

Post.any_instance.
  should_receive(:update_attributes).
  with({"these" => "params"})
put :update, :id => "1", :post => {"these" => "params"}

要测试调用update_attributes产生的两条路径,请替换期望值:

it "should redirect when successful" do
  Post.any_instance.
    should_receive(:update_attributes).
    with({"these" => "params"}).
    and_return(true)`
  response.should_redirect_to(post_path(@mock_post))
  put :update, :id => "1", :post => {"these" => "params"}
end

it "should render the edit page when unsuccessful" do
  Post.any_instance.
    should_receive(:update_attributes).
    with({"these" => "params"}).
    and_return(false)`
  response.should render_template("edit")
  put :update, :id => "1", :post => {"these" => "params"}
end