检查集合的RSpec匹配器包括满足lambda的项目

时间:2015-05-27 08:07:05

标签: ruby rspec rspec-rails rspec3

我对如何编写RSpec 3.2.x规范感到有点不知所措,该规范检查列表是否包含至少一个满足条件的项目。

以下是一个例子:

model = Invoice.new
model.name = 'test'
changes = model.changes
expect(changes).to include { |x| x.key == 'name' && x.value == 'test' }

更改列表中还会有其他(自动)更改,所以我不想验证只有一个特定的更改,我也不想依赖于排序expect(changes.first)...所以我基本上需要一种方法来指定列表中至少有一个变化满足条件。

我可以这样做:

result = changes.any? { |x| x.key == 'name' .. }
expect(result).to eq(true)

但是那时rspec失败不会给我任何有意义的输出,所以我认为必须有一种内置的方法来匹配它。

欢迎任何其他关于如何构建测试的建议。

编辑:要清楚 - 更改是ChangeObject的列表,因此我需要访问他们的.key.value方法

2 个答案:

答案 0 :(得分:2)

在RSpec 3中,matchers are fully composable,这意味着您可以将实现Ruby ===协议(包括匹配器!)的任何对象传递给include,它将正常工作。 Ruby 1.9中的Lambdas实现了===协议,这意味着你可以这样做:

expect(changes).to include(lambda { |x| x.key == 'name' && value == 'test' })

那就是说,这不会给你一个很好的失败信息(因为RSpec无法生成lambda的描述)。我不确定value来自您的示例,但如果它是x.value,您可以使用have_attributes(或an_object_having_attributes更好可读性)匹配器:

expect(changes).to include an_object_having_attributes(key: 'name', value: 'test')

答案 1 :(得分:1)

试试这个

expect(changes).to be_any{ |x| //logic to match }