2011-10-03 73 views
3

当我继续学习使用RSpec 2和Rails 3.1的TDD时,我似乎无法找到解决此问题的方法。带RSpec和Rails的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 

,并在我的UsersController,

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: 

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

有什么建议吗?

回答

3

您的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 
+0

我见,我认为测试会(并且应该)通过,因为它确实分配了一个@user变量。换句话说,应用程序代码正在做我正在测试的内容。看起来我需要实现比测试需要传递更多的应用程序代码,因为我还没有测试渲染模板或用户重定向到的位置。 – Feech

+1

没错。在测试中有错误和失败。你的测试没有遇到失败(如果@user是'nil'或者不是'User'),那么测试就会失败。失败或错误被认为是不成功的测试。 – aNoble

+0

感谢您的帮助aNoble。我想我会保持我的控制器测试模式,首先测试正确的渲染/重定向,然后继续发生其他事情。 – Feech

-1

我遇到这家最近我自己。似乎有一种可能性是在你的测试中挽救错误。

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 
+0

是的,RSpec控制器测试跟随呈现/重定向并产生错误没有任何意义。 – Feech

+0

异常处理应该是例外 –

2

要测试渲染什么,你会想:

expect(response).to render_template(nil)