我需要用测试覆盖我的Ruby on Rails代码。我使用RSpec进行测试。
有什么方法可以根据实例模拟对实例的调用? (kind_of?
)。我想测试给定父类的子代是否被调用。我希望有类似allow_any_kind_of
的方法,类似于allow_any_instance_of
。但是我找不到类似的东西。
这是我的代码示例。我有Base
个课程,还有几个孩子。在测试中,使用哪个确切的孩子并不重要。
class Parent
def my_method; end
end
class ChildA < Parent; end
class ChildB < Parent; end
class App
def apply
[ChildA.new, ChildB.new].all? { |c| c.my_method }
end
end
我的RSpec测试。它失败是因为ChildA或ChildB都不是Parent类的实例。我可以有多个allow_any_instance_of
来覆盖所有Parent
的子级,但是我想保持简单,因为在实际代码中会有更多的子级。
context "#apply" do
before do
allow_any_instance_of(Parent).to receive(:my_method).and_return(true)
end
it "returns true" do
expect(subject.apply).to be_truthy
end
end
我认为没有直接方法可以设定任何子类实例的期望。但是,将依赖项注入您的方法将使您更容易对其进行测试。
您可以用类似于以下的方式重写它:
class App
def initialize(params_hash)
@children = params_hash[:children] || [ChildA.new, ChildB.new]
end
def apply
children.all? { |c| c.my_method }
end
private
attr_reader :children
end
然后您可以在测试中执行类似以下操作:
describe "#apply" do
it "returns true" do
children =
[
instance_double('SubClassA', my_method: true),
instance_double('SubClassB', my_method: true),
]
children.each { |c| expect(c).to receive(:my_method) }
app = App.new(children: children)
expect(app.apply).to be true
end
end
使用expect_any_instance_of
可能表示代码有气味,每当我开始考虑使用它时,我都会暂停并查看我的代码,并验证是否可以用更好的方式编写它,以便于测试和依赖注入使代码易于测试。
这里您想要做的是钩在apply方法内部,并验证它的作用,但是测试中的客户代码无法检查其中的情况。因此我会在我认为合理且合理的情况下,注入依赖项并对其设置期望。