如何通过Rspec测试Proc的分配?

时间:2018-02-18 01:51:43

标签: ruby testing lambda rspec

我正在使用DataMapper宝石。

我有一些代码可以根据某些规则动态创建表。所以我有一行代码如下:

def set_table_name(table_name:)
  adapter = DataMapper.repository(:default).adapter
  adapter.resource_naming_convention = lambda { |_| table_name }
end

这直接来自他们的文档:http://www.rubydoc.info/github/datamapper/dm-core/DataMapper/NamingConventions

这很好用,但我想编写一个规范,知道它正确设置了命名约定。如果它不是lambda而只是设置值,那么我可能会这样做:

# assume 'adapter' is already set in the test, either as a mock or whatever
expect(adapter).to receive(:resource_naming_convention=).with("some_value")
something.set_table_name(table_name: "some_value")

由于DataMapper是一个外部依赖项,我不知道setter有什么副作用或要求,所以我只想验证它是否被正确调用。

然而,由于它是用lambda调用的,我不知道该怎么做。我可以这样做:

# assume 'adapter' is already set in the test, either as a mock or whatever
expect(adapter).to receive(:resource_naming_convention=).with(kind_of(Proc))
something.set_table_name(table_name: "some_value")

但我真的很想验证那个" some_value"是Proc。的执行值。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

一种方法是将lamda解压缩到一个函数并将其存根:

def set_table_name(table_name:)
  adapter = DataMapper.repository(:default).adapter
  adapter.resource_naming_convention = naming_convention_lambda
end

def naming_convention_lambda
  lambda { |_| table_name }
end

# in tests ...

fn = lambda { |_| table_name }
expect(something).to(
  receive(:naming_convention_lambda).and_return(fn)
)
expect(adapter).to(
  receive(:resource_naming_convention=).with(fn)
)

如果您愿意,可以单独测试lambda。

此外,您可以将lambda更改为proc并删除|_|位,因为它不需要正确的参数长度。