【发布时间】:2016-05-05 13:21:34
【问题描述】:
我在控制器中有一个私有方法
private
def body_builder
review_queue = ReviewQueueApplication.where(id: params[:review_queue_id]).first
...
...
end
我只想测试body_builder 方法,它是一种为rest 客户端api 调用构建有效负载的方法。但是,它需要访问参数。
describe ReviewQueueApplicationsController, type: :controller do
describe "when calling the post_review action" do
it "should have the correct payload setup" do
@review_queue_application = ReviewQueueApplication.create!(application_id: 1)
params = ActionController::Parameters.new({ review_queue_id: @review_queue_application.id })
expect(controller.send(:body_builder)).to eq(nil)
end
end
end
如果我运行上述程序,它将发送body_builder 方法,但随后它将中断,因为参数尚未正确设置,因为它们将在调用操作中。
我总是可以为body_builder 方法创建一个条件参数,这样它要么接受一个参数,要么使用像def body_builder(review_queue_id = params[:review_queue_id]) 这样的参数,然后在测试controller.send(:body_builder, params),但我觉得更改代码使测试通过是错误的,它应该按原样进行测试。
如何在将私有方法发送给控制器之前将参数输入控制器?
【问题讨论】:
-
我的建议是使用正确的参数实际调用 RESTful 入口点。如果在调用 body_builder 方法之前必须发生某些行为,则可以模拟和存根以将执行引导到正确的路径。然后,您对 controller.body_builder 方法寄予期望,而不仅仅是调用它。我意识到这比仅仅调用私有方法要重,但我一直觉得,如果直接在测试中调用私有私有方法,那么你有点跨出了该对象的测试“沙箱”。
-
@jaydel,我完全明白你来自哪里,唯一的问题是测试对入口点的实际调用是它会触发已经测试过的
RestClient::Request操作,我希望假设该部分正常工作,但忽略了有效负载的构建,如果我们向有效负载添加它不希望它会失败的东西。 -
是的,我理解您的担忧。我不熟悉该特定行为的细节,但是否可以模拟和存根该部分以您想要测试的方式构建有效负载。我已经在我理解的范围之外徘徊,当然,你比我更了解它。所以只是深思
-
这是您提出的一个很好的问题。我经历了很多关于这个问题的有争议的对话。无论出于何种原因,这个话题似乎都有一些“宗教”。我倾向于避免盲目地采取这些立场,并且在很多方面仍未解决,所以我会关注这个问题:)
-
是的,我也有同样的感觉,我们一直都这样分解控制器中的代码,并且能够根据其职责测试每个方法是有意义的。但是拥有一个像参数这样的全局状态使得很难单独测试它们。你必须时刻注意后台的黑魔法。
标签: ruby-on-rails rspec controller private-methods