我想知道这是否是在我的测试中避免调用第三方服务的好策略。
我有2个类封装了对第三方服务的调用,我称之为PersonIdentifier和FIleManager。
为了使这些类可测试,我将它们传递给另一个类的构造函数,如下所示:
CreateContact.new(current_user, input, PersonIdentifier.new, FileManager.new)
但是,此CreateContact实例的创建可能在类方法或实例方法中。因此,在类方法的情况下,我创建另一个创建实例的类方法,例如
def self.create_contact(current_user, input)
CreateContact.new(current_user, input, PersonIdentifier.new, FileManager.new)
end
然后在我的测试中,我使用instance_eval来覆盖这个方法,例如
def setup
super
EmailIdentifier.instance_eval do
def create_contact(current_user, input)
CreateContact.new(current_user, input, TestPersonIdentifier.new, TestFileManager.new)
end
end
end
在我的测试设置中添加多个class_eval或instance_eval会有点痛苦。
有更好的方法吗?
答案 0 :(得分:0)
首先,在您的代码中,依赖性太强了。
def self.create_contact(current_user, input)
CreateContact.new(current_user, input, PersonIdentifier.new, FileManager.new)
end
您在代码中隐式调用了两个外部对象。
我将首先重构代码以允许依赖注入
def self.create_contact(user, input, person_identifier=nil, file_manager=nil)
# current_user seems very specific, replaced by a general name 'user'
person_identifier ||= PersonIdentifier.new
file_manager ||= FilerManager.new
new(user, input, person_identifier, file_manager)
end
通过这种方式,任何实例都可以注入到这个方法中,你已经从这两个类中删除了依赖。
然后,在测试中,您需要的是简单地模拟这两个实例。我只熟悉Rspec所以不能提供具体的代码,但原理是一样的。