【问题标题】:TDD with RSpec and Rails: testing controller actions with no view使用 RSpec 和 Rails 的 TDD:在没有视图的情况下测试控制器操作
【发布时间】:2011-10-03 20:44:09
【问题描述】:

随着我继续学习使用 RSpec 2 和 Rails 3.1 的 TDD 方法,我似乎无法找到解决这个问题的方法。

我有一个带有新和创建操作的用户控制器。在我的 UsersController 规范中,我有

users_controller_spec.rb

describe "POST 'create'" do
  before(:each) do
    @attr = Factory.attributes_for(:user)
  end

  it "should assign an @user variable" do
    post :create, :user => @attr
    assigns[:user].should_not be_nil
    assigns[:user].should be_kind_of(User)
  end
end

在我的用户控制器中,

users_controller.rb

def create
  @user = User.new(params[:user])
end

这个规范失败了

1) UsersController POST 'create' should assign an @user variable
   Failure/Error: post :create, :user => @attr
   ActionView::MissingTemplate:

我可以继续实现应用程序代码以通过此测试,但我觉得此测试应该按原样通过。

有什么建议吗?

【问题讨论】:

    标签: ruby-on-rails-3 rspec


    【解决方案1】:

    您的create 方法需要做一些事情。呈现模板或重定向。由于您没有告诉它重定向,因此假设您希望它呈现模板,但是当它找不到 create.html.erb 文件时,它会引发错误。

    最好的办法是这样做:

    def create
      @user = User.new(params[:user])
      redirect_to root_url
    end
    

    或者这个:

    def create
      @user = User.new(params[:user])
      render :nothing => true
    end
    

    【讨论】:

    • 我明白了,我认为测试会(并且应该)通过,因为它确实分配了一个 @user 变量。换句话说,应用程序代码正在做我正在测试的事情。似乎我需要实现比测试通过所需更多的应用程序代码,因为我还没有测试渲染的模板或用户重定向的位置。
    • 对。在测试中有错误和失败。您的测试没有失败(如果@user 是nil 或者不是User),它就会出错。失败或错误都被认为是不成功的测试。
    • 感谢 aNoble 的帮助。我想我会保留我的控制器测试模式,首先测试正确的渲染/重定向,然后继续进行其他应该发生的事情。
    【解决方案2】:

    测试你不需要的渲染:

    expect(response).to render_template(nil)
    

    【讨论】:

      【解决方案3】:

      我最近自己也遇到过这个问题。似乎一种可能性是挽救测试中的错误。

      it "should assign an @user variable" do
        begin
          post :create, :user => @attr
        rescue ActionView::MissingTemplate
          # This is okay because(/as long as) we test the render/redirect
          # in a separate spec where we don't rescue this exception.
        end
        assigns[:user].should_not be_nil
        assigns[:user].should be_kind_of(User)
      end
      

      我不知道这个解决方案有多“正确”。一方面,它肯定强调“一次测试一件事”的心态,另一方面,它看起来有点丑。

      编辑

      我想你可以在你的规范助手中制作一些不错的包装器,比如

      def post?(action, params = {})
        post action, params
      rescue ActionView::MissingTemplate
      end
      

      【讨论】:

      • 是的,RSpec 控制器测试跟随渲染/重定向并产生错误是没有意义的。
      • 异常处理应该是异常的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-22
      • 2012-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多