集成测试:在控制器中创建vs新

时间:2009-12-31 02:24:01

标签: ruby-on-rails testing tdd integration-testing

已修改:遵循建议。请参阅问题末尾。

我有一个带两个功能的控制器:

 def new
     if login_required
            @discussion = Discussion.new
            respond_to do |format|
                  format.html # new.html.erb
                  format.xml  { render :xml => @discussion }
            end
      end
 end


 def create
     if login_required
         @discussion = Discussion.new(params[:discussion])
         @discussion.update_attribute("user_id",session[:userid])
         respond_to do |format|
         if @discussion.save
            flash[:notice] = 'Discussion was successfully created.'
            format.html { redirect_to(@discussion) }
            format.xml  { render :xml => @discussion, :status => :created, :location => @Discussion }
        else
            format.html { render :action => "new" }
            format.xml  { render :xml => @discussion.errors, :status => :unprocessable_entity }
        end
   end
 end
end

现在,在我的集成测试文件中,我有:

test "test 1" do  
   post "/users/login",:user=> { :name => "bob", :password => "test_pass" }
   post "/discussions/create", :discussion => { :title => "title 1", :body => "discussion body", :id => "101"} #Create 1
   assert_response :success       #Assert 1
   get "/discussions/101"
   assert_response :success       #Assert 2
end

但是,我在Assert 1上得到302

如果我将“创建1”更改为:     发表“/ discussion / new”,:discussion => {:title => “title 1”,:body => “讨论正文”,:id => “101”}

我收到404错误。

1)发生了什么事?

2)我可以使用哪些工具/选项,以便我自己解决这个问题?

由于

更新

随后的建议(来自Ryan Bigg):

  • post:create,{:discussion => {}},{:user_id =>用户(:bob).id}

结果:

  • Rack :: Lint :: LintError:env变量HTTP_USER_ID具有非字符串值1976283457

仍未解决。

2 个答案:

答案 0 :(得分:2)

有几件事:

  1. 尝试将login_required移至before_filter
  2. 对于您的测试,您应该post :create, :discussion => { ... }。如果您已正确设置,测试应该已经知道控制器。我相信命名惯例是DiscussionsControllerTest
  3. 我认为你为什么在Assert 1上获得302,因为它实际上没有登录。尝试在调用post时传递凭据:

    post :create, { :discussion => { } }, { :user_id => users(:bob).id }
    

    post的第二个参数是参数Hash,第三个参数是会话Hash。如果您已经加载了用户设备并且他们有一个名为bob的密钥,则应该找到并使用他登录。

    我在 RSpec 测试中使用的替代解决方案是定义一个login_as方法,该方法接受我应该登录的用户登录的单个参数。然后,我在控制器或集成测试中执行的每个请求都以该用户身份登录:

    def login_as(name)
      request.session[:user] = users(name).id
    end
    

    我认为您应该能够在test_helper.rb文件中执行相同的操作,但是......我还没有尝试过。 YMMV。

答案 1 :(得分:0)

一切似乎都在你的控制器中正常工作。在您的测试中,您正在发送POST请求,new操作不接受POST请求,但只接受GET。 create操作接受POST,但在成功创建讨论后会发送重定向。

您应该将第一个assert_response :success替换为:

assert_redirected_to :controller => "discussions", :action => "show"`