如何测试服务对象方法?

时间:2015-09-25 18:01:54

标签: rspec-rails

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

我的服务文件如下......

class ExampleService

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

  private

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

end

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

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

2 个答案:

答案 0 :(得分:4)

如何测试服务对象方法?

简短回答:根本不进行测试

答案很长:看过Sandi Metz advice on testing之后,你会同意,并且你会想要测试她的方式。

这是基本的想法:

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

要做的测试摘要:

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

取自会议的slides

答案 1 :(得分:3)

在您的第一个示例中,您的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

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