如何测试服务对象方法的调用?

tob*_*b88 1 rspec-rails

我正在尝试为我的服务对象建立一些测试。

我的服务文件如下...

class ExampleService

  def initialize(location)
    @location = coordinates(location)
  end

  private

  def coordinates(location)
    Address.locate(location)
  end

end
Run Code Online (Sandbox Code Playgroud)

我想测试私有方法是否由公共方法调用。这是我的代码...

subject { ExampleService.new("London") }

it "receives location" do
  expect(subject).to receive(:coordinates)
  subject
end
Run Code Online (Sandbox Code Playgroud)

但是我得到这个错误...

expected: 1 time with any arguments
received: 0 times with any arguments
Run Code Online (Sandbox Code Playgroud)

Pet*_*vin 5

在您的第一个示例中,当您对其设置期望时,您subject已经被实例化/初始化(通过传递给expect,在过程中调用coordinates),因此期望无法成功:coordinates。另外,顺便说一句,它subject已被记忆,因此后面的行中不会有额外的实例化。

如果您想确保初始化调用特定方法,您可以使用以下命令:

describe do
  subject { FoursquareService.new("London") }
  it "receives coordinates" do
    expect_any_instance_of(FoursquareService).to receive(:coordinates)
    subject
  end
end
Run Code Online (Sandbox Code Playgroud)

另请参阅Rails / RSpec:如何测试 #initialize 方法?


Ale*_*bio 5

如何测试服务对象方法的调用?

简短答案:完全不测试

长答案:在看到Sandi Metz关于测试的建议后,您将同意,并且将想要测试她的方式。

这是基本思想:

  • 您的类的公共方法(公共API)必须经过测试
  • 私有方法不需要测试

测试摘要:

  • 传入查询方法,测试结果
  • 传入的命令方法,测试直接的公共副作用
  • 外发命令方法,期望发送
  • 忽略:发送给自己,命令给自己以及向他人查询

摘自会议幻灯片