如何Foo.bar在不测试bar方法行为(已在其他地方测试过)的情况下测试以下示例中调用的内容?
# Code
class Alpha
def process
Foo.bar
end
end
Run Code Online (Sandbox Code Playgroud)
以下是我到目前为止的规范.不幸的是,这种方法抛出了"已经定义的类"警告,因为Foo已经在我的项目的其他地方定义过了.
# Spec
let(:alpha) { Alpha.new }
let(:klass) { MiniTest::Mock.new }
subject { alpha.process }
it "calls Foo.bar" do
klass.expect(:bar, '') # Define method call expectation
Foo = klass # Redefine Foo as a mock object
subject # Run method being tested
klass.verify # Confirm method was called
end
Run Code Online (Sandbox Code Playgroud)
我不希望我的测试依赖于Foo类,因为这是一个外部依赖,我不想测试响应值Foo.bar,因为这可能会随意改变.
为了模拟这样的类,你必须插入一个注入点,如下所示:
class Alpha
def initialize(opts = {})
@foo_class = opts[:foo_class] || Foo
end
def process
@foo_class.bar
end
end
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为类名在Ruby中只是一个常量,可以像任何其他值一样赋值.因此,不是硬编码对Foo类的调用Alpha,而是在新@foo_class实例变量指向的任何内容上调用方法.大多数情况下,Foo除非你传递其他内容,否则这仍然是课堂.我通常将这样的模拟参数隐藏为可选参数,就像我在这里做的那样.我也没有在最终用户目标文档中包含对它们的引用,因为它们在技术上不是我认为是公共API的一部分.
然后在测试中,您可以Alpha像这样初始化对象:
fooClassMock = MiniTest::Mock.new
fooClassMock.expect(:bar, '')
alpha = Alpha.new(:foo_class => fooClassMock)
Run Code Online (Sandbox Code Playgroud)
你应该得到你正在寻找的结果.
| 归档时间: |
|
| 查看次数: |
1810 次 |
| 最近记录: |