0

我想知道这是否是在我的测试中避免调用 3rd 方服务的好策略。

我有 2 个类,它们封装了对我称为 PersonIdentifier 和 FIleManager 的 3rd 方服务的调用。

为了使这些类可测试,我将它们传递给另一个类的构造函数,如下所示:

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 有点痛苦。

有没有更好的办法?

4

1 回答 1

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,所以不能提供具体的代码,但原理是一样的。

于 2013-09-11T05:07:22.013 回答