我对如何编写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
方法
答案 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 }