2016-11-30 67 views
1

我有一个测试控制器动作的rspec测试。测试控制器在RSpec中的重定向

class SalesController < ApplicationController 
    def create 
    # This redirect sends the user to SalesController#go_to_home 
    redirect_to '/go_to_home' 
    end 

    def go_to_home 
    redirect_to '/' 
    end 
end 

我控制器测试看起来像

RSpec.describe SalesController, type: :controller do 
    include PathsHelper 

    describe 'POST create' do 
    post :create 

    expect(response).to redirect_to '/' 
    end 
end 

然而,当我运行测试它告诉我,:

Expected response to be a redirect to <http://test.host/> but was a redirect to <http://test.host/go_to_home>. 
    Expected "http://test.host/" to be === "http://test.host/go_to_home". 

/go_to_home将发送用户SalesController#go_to_home。我如何测试该响应最终将导致主页的网址为http://test.host/

回答

1

控制器测试是有效的单元测试 - 您正在测试调用单个动作的效果以及该动作的预期行为。

create动作确实与302状态码返回一个响应返回,并且包括在所述报头中的Location指示新的URI,它在呼叫建立将Location: http://localhost/go_to_home

的情况下这是尽可能的控制器测试进行。它模拟了从浏览器到创建操作的调用并接收到初始重定向。

在现实世界中,浏览器当然会导航到给定的位置,然后打到go_to_home动作,但这超出了控制器测试的范围......这是集成测试领域。

所以,要么,

  1. 创建一个集成测试最初叫create动作,请您在“/”结束的重定向和测试。
  2. 改变控制器测试expect(response).to redirect_to '/go_to_home'
  3. 更改create行动直接重定向到“/”
2

为什么期望在规格中重定向到'/'? 从你粘贴你会被重定向到/ go_to_home“打黑创建行动

尝试改变规格后的控制器代码:

expect(response).to redirect_to '/go_to_home' 

编辑:

这是一个真正的示例或代码只是为了分享您想要实现的目标? 我不认为rspec在去'/ go_to_home'后会跟着重定向,我觉得很好。

如果您正在测试创建操作,则可以将测试重定向到“/ go_to_home”,因为这是操作的过程。 然后,您可以为其他操作go_to_home做另一个测试,并期望重定向到根。

你是否正在从别处调用行为'go_to_home'?

+0

我会澄清我的问题。 '/ go_to_home'会将用户发送到SalesController#go_to_home。 – jason328

+0

不,我只从SalesController#create调用go_to_home。了解我已经简化了这个例子,所以有很多逻辑缺失。 – jason328