ruby – 为什么Minitest的assert_raises在这种情况下不能按预期
我试图使用
Action Controller bug report template在Rails中解决一个奇怪的行为.
对于记录,这是模板中的控制器: class TestController < ActionController::Base include Rails.application.routes.url_helpers def index render text: 'Home' end end 我添加了一个缺少动作的路线: 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来排除得到线程或东西但无法找到任何东西. 我也看了implementation of 为什么assert_raises(AbstractController :: ActionNotFound){get’/ missing’}没有通过? (不要紧,这已经在Rails中测试了.我正试图通过这个来实现真正的交易.) 解决方法
这不是assert_raises的问题,继续工作得很好.您遇到的问题是,您在Rails应用程序中引发的异常将由您的Rails应用程序处理,而不会传播到您的测试中.调用get’/ missing’会引发AbstractController :: ActionNotFound错误,但随后您的应用会处理错误并向客户端(您的测试)返回适当的响应(404或500).
好的,那你怎么去测试你的控制器确实引起了你期望的错误呢?通常,您只需使用ActionController :: TestCase测试来测试控制器.但是,当您在不在ActionController :: TestCase中的控制器上调用操作时,您会收到不同的错误.所以以下内容: 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测试的东西.而不是通过完整的Rails应用程序进行调用,让我们尝试直接调用TestController.如果我们创建一个新的控制器实例,我们可以要求它处理一个动作,即使该动作没有在控制器上定义.但要做到这一点,我们必须深入了解ActionController的工作原理并使用 require "test_helper" class TestControllerTest < Minitest::Test def test_missing assert_raises AbstractController::ActionNotFound do TestController.new.process :missing end end end 现在我们要求控制器处理不存在的操作并测试控制器的行为是否符合预期.好极了? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |