gpt4 book ai didi

ruby - 为什么 Minitest 的 assert_raises 在这种情况下没有按预期工作?

转载 作者:数据小太阳 更新时间:2023-10-29 07:11:07 26 4
gpt4 key购买 nike

我正在尝试使用 Action Controller bug report template 解决 Rails 中的一个奇怪行为.

为了记录,这是模板中的 Controller :

class TestController < ActionController::Base
include Rails.application.routes.url_helpers

def index
render text: 'Home'
end
end

我已经为缺失的 Action 添加了一条路线:

routes.draw do
get '/' => 'test#index'
get '/missing' => 'test#missing'
end

并且我试图断言 AbstractController::ActionNotFound 在遵循该路线时被引发:

class BugTest < Minitest::Test
include Rack::Test::Methods

def test_missing
assert_raises(AbstractController::ActionNotFound) { get '/missing' }
end

private
def app
Rails.application
end
end

预期行为:绿色测试。

实际行为:

# Running tests:

D, [2014-04-24T09:17:41.948985 #4497] DEBUG -- :
D, [2014-04-24T09:17:41.949029 #4497] DEBUG -- :
I, [2014-04-24T09:17:41.949094 #4497] INFO -- : Started GET "/missing" for 127.0.0.1 at 2014-04-24 09:17:41 +0200
F, [2014-04-24T09:17:41.951337 #4497] FATAL -- :
AbstractController::ActionNotFound (The action 'missing' could not be found for TestController):
[stacktrace]

1) Failure:
BugTest#test_missing [action_controller_gem.rb:45]:
AbstractController::ActionNotFound expected but nothing was raised.

所以,基本上,引发了异常,但 Minitest 声称没有引发任何异常。我在这里被难住了。

为什么 Minitest 不能断言 AbstractController::ActionNotFound 被引发了?我查看了 Rack::Test::Methods 以排除 get 与线程或其他东西一起工作但找不到任何东西。

我还查看了 implementation of assert_raises -- 没有什么明显的。

为什么 assert_raises(AbstractController::ActionNotFound) { get '/missing' } 没有通过?

(不要介意这已经在 Rails 中测试过的事实。我正在努力克服这个问题以获得真正的交易。)

最佳答案

这不是 assert_raises 的问题,它继续正常工作。您遇到的问题是您在 Rails 应用程序中引发的异常正在由您的 Rails 应用程序处理,而不是传播到您的测试。调用 get '/missing' 会引发 AbstractController::ActionNotFound 错误,但随后您的应用会处理错误并向客户端返回适当的响应(404 或 500)(你的测试)。

好的,那么您将如何测试您的 Controller 是否确实引发了您预期的错误?通常,您只需使用 ActionController::TestCase 测试来测试您的 Controller 。但是,当您在不在 ActionController::TestCase 中的 Controller 上调用操作时,您会得到一个不同的错误。所以如下:

require "test_helper"

class TestControllerTest < ActionController::TestCase

def test_missing
assert_raises AbstractController::ActionNotFound do
get :missing
end
end
end

产生以下输出:

  1) Failure:
TestControllerTest#test_missing [test/controllers/test_controller_test.rb:6]:
[AbstractController::ActionNotFound] exception expected, not
Class: <ActionController::UrlGenerationError>
Message: <"No route matches {:action=>\"missing\", :controller=>\"test\"}">
---Backtrace---
test/controllers/test_controller_test.rb:7:in `block in test_missing'
test/controllers/test_controller_test.rb:6:in `test_missing'
---------------

原因是因为 ActionController::TestCase 知道路由并且不允许调用不在路由中的操作。但这正是您要测试的。而且,我假设您为什么不使用 ActionController::TestCase

在这一点上,我想知道您是否没有测试一些您不应该做的事情。也许您应该允许 Rails 完成它的工作并相信它的行为是正确的。但是,嘿,我们已经走到这一步了,为什么不一路走下去,测试一下 Rails 测试的内容。让我们尝试直接调用 TestController,而不是通过完整的 Rails 应用程序进行调用。如果我们创建 Controller 的一个新实例,我们可以要求它处理一个 Action ,即使该 Action 没有在 Controller 上定义。但要做到这一点,我们将不得不深入研究 ActionController 的工作原理并利用 AbstractController#process方法:

require "test_helper"

class TestControllerTest < Minitest::Test
def test_missing
assert_raises AbstractController::ActionNotFound do
TestController.new.process :missing
end
end
end

现在我们要求 Controller 处理一个不存在的 Action ,并测试 Controller 的行为是否符合预期。好吗?

关于ruby - 为什么 Minitest 的 assert_raises 在这种情况下没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23264064/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com