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

How to test service object methods are called?

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

我的服务文件如下...

class ExampleService

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

  private

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

end

我想测试私有方法是否被 public 方法调用。这是我的代码...

subject { ExampleService.new("London") }

it "receives location" do
  expect(subject).to receive(:coordinates)
  subject
end

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

expected: 1 time with any arguments
received: 0 times with any arguments

在您的第一个示例中,您的 subject 已经 instantiated/initialized(通过传递给 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

另见 Rails / RSpec: How to test #initialize method?

如何测试服务object方法被调用?

简答:根本不测试

长答:看完Sandi Metz advice on testing,你会同意的,你会想测试她的方式。

这是基本思路:

  • 你的class(publicAPI)的public方法必须测试
  • 私有方法不需要测试

要做的测试总结:

  • 传入查询方法,测试结果
  • 传入命令方法,测试直接public副作用
  • 外发命令方式,期待发送
  • 忽略:发送给自己,命令给自己,查询给别人

摘自会议 slides