【发布时间】:2018-12-19 00:25:14
【问题描述】:
我一直在使用in this article 描述的技术在我的请求规范中模拟控制器中的方法。 TLDR,该技术使用“allow_any_instance_of”来模拟控制器方法。我发现了一些似乎与这篇文章一致的其他 StackOverflow 帖子。
但是,在阅读rspec 3.8 documentation 时,它会显示以下内容:
- rspec-mocks API 是为单个对象实例设计的,但此功能对整个对象类都有效。因此,存在一些语义上令人困惑的边缘情况。例如,在 expect_any_instance_of(Widget).to receive(:name).twice 中,不清楚特定实例是否应该接收 name 两次,或者是否预期两个接收总数。 (是前者。)
- 使用此功能通常是一种设计味道。可能是您的测试试图做的太多,或者被测对象太复杂。
- 它是 rspec-mocks 中最复杂的功能,历史上收到的错误报告最多。 (核心团队中没有人积极使用它,这无济于事。)
在请求规范中模拟方法的正确和“现代”方式是什么?
我认为以下几点不重要,但以防万一:
- Rails 5.2
- Ruby 2.4.1
- RSpec 3.8
编辑:添加一些示例代码。
module A
def my_pain
puts "I don't want to run this during testing"
end
end
class TestController < ApplicationController
include A
def index
my_pain
end
end
那么在控制器/请求测试中使用 RSpec 模拟“#my_pain”时测试“#index”的现代方法是什么。
【问题讨论】:
-
关于您对第一个答案的评论(联系其他服务):您是否考虑过使用 vcr/webmock 制作(最初)、保存、然后伪造/重播响应?您可以提出一次请求,修改 yml 文件(如果需要对其进行通用化,删除秘密或其他内容),它将重播,而无需将来与远程建立任何连接
-
如果你能提供一个具体的例子,我可以告诉你我将如何测试它。
-
@JayDorsey 我没有看过 vcr/webmock。我会看看那些。从你的描述来看,这听起来很有希望。然而,虽然这可能会解决我现在关心的问题,但我是在更一般的背景下提出这个问题的。
-
@aridlehoover 希望格式正确显示:模块 A def my_pain 将“我不想在测试中运行它” end end class TestController
-
@aridlehoover 显然我试图在 cmets 中放置一个代码示例并没有成功。我用一个例子编辑了原始帖子。
标签: ruby-on-rails unit-testing rspec rspec-rails