ruby-on-rails - 如何使用 minitest 在控制器上测试私有方法?
问题描述
非常新的测试
我有一个无模型的 Rails 应用程序,带有一个名为“PokerController”的控制器
在 poker_controller.rb 中,我有一个如下所示的私有方法:
private
def test(x)
1 + x
end
然后我在测试/控制器中有一个名为“poker_controller_test.rb”的文件
我正在尝试做这样的事情:
require 'test_helper'
class PokerControllerTest < ActionController::TestCase
test "check if test == 2" do
test = test(1)
assert test == 2
end
end
如您所见,我正在尝试将调用函数“test”的结果保存到名为“test”的变量中,然后我正在检查是否 == 2。
基本上,我试图将一个数字(在本例中为“1”)传递给测试方法,并且我希望测试将 1 加到 1,并期望得到 2。
我确定我只是没有正确设置测试,但是如何调用这样的自定义方法然后评估返回的内容?
这是我的测试错误结果:
Error:
PokerControllerTest#test_check_if_test_==_2:
ArgumentError: unknown command "\x01"
test/controllers/poker_controller_test.rb:6:in `test'
test/controllers/poker_controller_test.rb:6:in `block in <class:PokerControllerTest>'
解决方案
你没有。
通常不赞成测试私有方法*。
在 Rails 中,您主要通过集成测试来测试控制器。这些测试向您的应用程序发送真正的 HTTP 请求,然后您编写有关响应或发送请求的副作用的断言。
“[...] 您可以测试设置了哪些 cookie、返回了哪些 HTTP 代码、视图的外观或数据库发生了哪些变化,但测试控制器的内部结构并不是一个好主意。”
——大卫·海涅迈尔·汉森
集成测试的一个例子是:
require "test_helper"
class PokerControllerTest < ActionDispatch::IntegrationTest
test "can see the welcome page" do
get "/path/to/somewhere"
assert_select "h1", "Welcome to my awesome poker app"
end
end
如果您有一个要单独测试的方法,它首先不属于您的控制器,并且可以说它也不应该是私有方法。
您应该测试对象的公共 API。控制器的公共 API 是通过路由器响应 HTTP 请求的方法。
ActionController::TestCase
不鼓励在遗留应用程序之外使用。
新的 Rails 应用程序不再生成函数式控制器测试,它们只能用于向后兼容。集成式控制器测试执行实际请求,而功能式控制器测试仅模拟请求。此外,集成测试与功能测试一样快,并提供了许多帮助程序,例如 parsed_body 用于有效测试控制器操作,甚至包括 API 端点。
除此之外,您的测试问题是您正在调用test
实例ActionController::TestCase
而不是控制器上的方法。然后,您通过定义具有相同名称的实例变量来隐藏该方法,这很少是一件好事。
即使您确实调用了控制器上的方法,Ruby 仍然会引发错误,因为您是从对象外部调用私有方法 - 这就是私有方法的全部意义所在。
虽然你可以通过调用它来违反封装,@controller.send(:test)
但这在很多层面上都是一个坏主意。
推荐阅读
- python - 当值更改和时间超过条件时,Pandas 数据帧中的增量计数
- python - 为什么使用描述符可以引入 __slots__?
- go - 如何使用 ReverseProxy 平衡跟踪连接数
- ios - SwiftUI - 隐藏视图时的动画
- python - 如何将 Pandas 系列转换为数据框
- javascript - 如何转换为高阶函数?
- wordpress - 在 React Native 中使用 WP Rest Api 更新配置文件
- elasticsearch - 在 Elasticsearch 中重新插入或重新标记而不丢弃所有内容
- ios - 使用当前上下文作为演示样式时一起关闭多个 ViewController
- a-star - Astar 寻路有时会停止工作