在我的Rails应用程序的功能测试中,我想测试我被重定向到的位置。预期的URL指向外部资源(这意味着它不是我的应用程序的一部分)。
网址如下所示:https://my.url.com/foo?bar1=xyz&bar2=123
不幸的是我无法预测参数,因为它们是由外部资源生成的。*
但是,网址的其余部分始终保持不变:https://my.url.com/foo
我通常使用assert_redirected_to
进行此类测试,但这需要整个网址,包括参数。
有人能想到另一种方法来测试重定向,但只检查没有参数的URL的第一部分吗?
(网址不在assigns
哈希)
*(我对应用程序进行API调用,使用我将重定向的URL进行响应)
答案 0 :(得分:18)
post
,get
等http请求命令在调用*时会创建一个名为@response
的实例变量。 @response
本身包含一个名为redirect_url
的方法,该方法存储您已重定向到的URL(如果您确实已被重定向)。
因此,我可以使用普通assert_match
将正则表达式与@response.redirect_url
进行比较:
post :my_action_to_test
assert_response :redirect
assert_match /https:\/\/my.url.com\/foo/, @response.redirect_url
*(实际上,这些http方法只使用私有方法process
,它创建@response
变量。)
答案 1 :(得分:2)
对此有两个快速的想法:
1)如果您的功能测试实际连接到外部应用程序,为什么不像通常那样从中获取params并测试重定向是否正确?
2)如果您的功能测试实际上没有连接到外部应用程序,那么您无论如何都要伪装它,所以我只是跳过测试重定向URL并尝试使用assert_response:redirect测试重定向。或者,创建一个模拟,返回重定向的URL,就好像它是外部应用程序一样,但是这样做可以让你从中获取params。
也就是说,不要因为你认为必须涵盖每一种可能的情况而进行测试。
答案 2 :(得分:1)
这个怎么样?它包装assert_redirected_to
以允许Regexp
作为第一个参数。但是,如果您尝试将Regexp
与Hash
匹配 - 只有String
,则无效。这样做会花费更多的工作。
ActionController::TestCase.class_eval do
old_assert_redirected_to = method(:assert_redirected_to)
define_method(:assert_redirected_to) do |*args|
if args.[0].kind_of?(Regexp)
assert_response(:redirect, args[1])
assert args[0] === @response.redirected_to
else
old_assert_redirected_to.bind(self).call(*args)
end
end
end
答案 3 :(得分:0)
我使用以下方法忽略任何查询字符串参数。它基于assert_redirected_to
# ignores any query string params eg. notice or alert messages for flash
def custom_assert_redirected_to(path)
assert_response :redirect
if path === Regexp
url = path
else
url = ActionController::Redirecting._compute_redirect_to_location(@request, path)
end
assert_equal url, @response.location.split("?").first
end