如何使用 minitest 在控制器上测试私有方法?
how do I test a private method on controller, using minitest?
测试新手
我有一个无模型的 rails 应用程序,它有一个名为“PokerController”的控制器
在 poker_controller.rb 中,我有一个如下所示的私有方法:
private
def test(x)
1 + x
end
然后我在 test/controllers
中有一个名为 '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 请求发送到您的应用程序,然后您编写有关响应或发送请求的副作用的断言。
"[...] You can test what cookies are set, what HTTP code is returned, how the view looks, or what mutations happened to the DB, but testing the innards of the controller is just not a good idea."
- David Heinemeier Hansson
集成测试的一个例子是:
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
如果您有一个要单独测试的方法,它首先不属于您的控制器,并且可以说它也不应该是私有方法。
您应该测试对象的 public API。控制器的publicAPI是通过路由器响应HTTP请求的方法。
ActionController::TestCase
的使用是discouraged outside of legacy applications。
New Rails applications no longer generate functional style controller
tests and they should only be used for backward compatibility.
Integration style controller tests perform actual requests, whereas
functional style controller tests merely simulate a request. Besides,
integration tests are as fast as functional tests and provide lot of
helpers such as as, parsed_body for effective testing of controller
actions including even API endpoints.
此外,您的测试存在的问题是您在 ActionController::TestCase
的实例上调用 test
方法,而不是在您的控制器上。然后,您通过定义一个具有相同名称的实例变量来隐藏该方法,这很少是一件好事。
即使您确实调用了控制器上的方法 Ruby 仍然会引发错误,因为您是从对象外部调用私有方法 - 这就是私有方法的全部意义。
虽然您可以通过调用 @controller.send(:test)
来违反封装,但这在很多层面上都是一个坏主意。
测试新手
我有一个无模型的 rails 应用程序,它有一个名为“PokerController”的控制器
在 poker_controller.rb 中,我有一个如下所示的私有方法:
private
def test(x)
1 + x
end
然后我在 test/controllers
中有一个名为 '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 请求发送到您的应用程序,然后您编写有关响应或发送请求的副作用的断言。
"[...] You can test what cookies are set, what HTTP code is returned, how the view looks, or what mutations happened to the DB, but testing the innards of the controller is just not a good idea."
- David Heinemeier Hansson
集成测试的一个例子是:
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
如果您有一个要单独测试的方法,它首先不属于您的控制器,并且可以说它也不应该是私有方法。
您应该测试对象的 public API。控制器的publicAPI是通过路由器响应HTTP请求的方法。
ActionController::TestCase
的使用是discouraged outside of legacy applications。
New Rails applications no longer generate functional style controller tests and they should only be used for backward compatibility. Integration style controller tests perform actual requests, whereas functional style controller tests merely simulate a request. Besides, integration tests are as fast as functional tests and provide lot of helpers such as as, parsed_body for effective testing of controller actions including even API endpoints.
此外,您的测试存在的问题是您在 ActionController::TestCase
的实例上调用 test
方法,而不是在您的控制器上。然后,您通过定义一个具有相同名称的实例变量来隐藏该方法,这很少是一件好事。
即使您确实调用了控制器上的方法 Ruby 仍然会引发错误,因为您是从对象外部调用私有方法 - 这就是私有方法的全部意义。
虽然您可以通过调用 @controller.send(:test)
来违反封装,但这在很多层面上都是一个坏主意。