Ruby RSpec匹配器,用于检查集合是否包含满足lambda的项

Ruby RSpec匹配器,用于检查集合是否包含满足lambda的项,ruby,rspec,rspec-rails,rspec3,Ruby,Rspec,Rspec Rails,Rspec3,对于如何编写RSpec3.2.x规范来检查列表是否包含至少一个满足条件的项,我有点不知所措 以下是一个例子: model = Invoice.new model.name = 'test' changes = model.changes expect(changes).to include { |x| x.key == 'name' && x.value == 'test' } 更改列表中还会有其他(自动)更改,因此我不想验证是否只有一个特定更改,也不想依赖排序expect(c

对于如何编写RSpec3.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
方法

expect(changes).to be_any{ |x| //logic to match }
在RSpec3中,这意味着您可以将实现Ruby的
===
协议的任何对象(包括匹配器!)传递到
include
,它将正常工作。Ruby 1.9中的lambda实现
==
协议,这意味着您可以执行以下操作:

expect(changes).to include(lambda { |x| x.key == 'name' && value == 'test' })
这就是说,这不会给您一个很好的失败消息(因为RSpec无法生成lambda的描述)。我不确定在您的示例中,
value
从何而来,但是如果它是
x.value
,您可以使用
have\u attributes
(或者
一个\u object\u have\u attributes
以提高可读性)匹配器:


不幸的是,这不起作用,因为它不是散列而是一个对象。我将澄清这个问题,我也不能检查匹配对象的相等性,因为该对象是在类内部构造的,我不想破坏可见性规则。在这种情况下,“expect(changes)。to be_包括{| x | x.key=='name'&&value=='test'}”Wild do job
be\u include
会抛出一个参数错误,但您为我指明了正确的方向
be|any{| x | |…}
为我解决了这个问题。请更新答案,以便我可以将其标记为已接受,这很好。我不知道
一个\u对象\u有\u属性
。非常感谢。它是RSpec 3.1中引入的新匹配器<;代码>;have_attributes的别名:
expect(changes).to include an_object_having_attributes(key: 'name', value: 'test')