我有一个充满对象的json数组。
my_array = [{id => 6, name => "bob"},
{id => 5, name => "jim"},
{id => 2, name => "steve"}]
我需要查看数组是否包含一个包含属性“id”的对象,该属性设置为5.“name”属性未知。
我如何在rspec中执行此操作?
我知道如果我知道我可以做的名字属性:
my_array.should include({:id => 5, :name => "jim"})
答案 0 :(得分:23)
expect(myArray.find { |item| item[:id] == 5 }).to_not be_nil
或遗留应用语法
myArray.find { |item| item[:id] == 5 }.should_not be_nil
请注意,myArray
不符合Ruby惯例。变量使用下划线
my_array
不是camelcase
myArray
答案 1 :(得分:3)
如果您正在执行其中的许多操作,这只会是值得的,但您可以定义custom matcher:
RSpec::Matchers.define :object_with_id do |expected|
match do |actual|
actual[:id] == expected
end
description do
"an object with id '#{expected}'"
end
end
# ...
myArray.should include(object_with_id 5)
答案 2 :(得分:2)
也可以使用hading_attributes别名:
expect(my_array).to include( an_object_having_attributes(id: 5) )
或者,就像我自己的用例一样,匹配整个数组:
expect(my_array).to contain_exactly(
an_object_having_attributes(id: 5),
an_object_having_attributes(id: 6),
an_object_having_attributes(id: 2)
)
答案 3 :(得分:1)
将此Nth-latest.bat "C:\somewhere" 2
匹配器放入any
,并在spec/support/matchers.rb
spec_helper.rb
然后你可以在这样的例子中使用它:
RSpec::Matchers.define :any do |matcher|
match do |actual|
actual.any? do |item|
matcher.matches?(item)
end
end
end
答案 4 :(得分:1)
您可以展开数组并检查两个数组的匹配,如下所示:
expect(my_array).to include(*compare_array)
它将展开并匹配数组的每个值。
它等同于:
expected([1, 3, 7]).to include(1,3,7)
答案 5 :(得分:0)
这是一个客户匹配器" include_object" (可能应该使用更好的名称,因为它只检查id是否存在)
使用如下
obj = {id:1}
objs = [{id: 1}, {id: 2}, {id: 3}]
expect(objs).to include_object obj
匹配器可以处理对象,哈希(符号或字符串) 它还会在异常中打印出数组中的id,以便于查看
RSpec::Matchers.define :include_object do |expected|
ids = []
match do |actual|
ids = actual.collect { |item| item['id'] || item[:id] || item.id }
ids.find { |id| id.to_s == expected.id.to_s }
end
failure_message_for_should_not do |actual|
"expected that array with object id's #{ids} would contain the object with id '#{expected.id}'"
end
failure_message_for_should_not do |actual|
"expected that array with object id's #{ids} would not contain the object with id '#{expected.id}'"
end
end
答案 6 :(得分:0)
我会像这样使用RSpec 3的可组合include
匹配器:
expect(my_array).to include(include(id: 5))
如果失败,这将通过RSpec获得更详细的输出。
it 'expects to have element with id 3' do
my_array = [
{ id: 6, name: "bob" },
{ id: 5, name: "jim" },
{ id: 2, name: "steve" }
]
expect(my_array).to include(include(id: 3))
end
这将生成以下失败消息:
Failures:
1) Test expects to have element with id
Failure/Error: expect(my_array).to include(include(id: 3))
expected [{:id => 6, :name => "bob"}, {:id => 5, :name => "jim"}, {:id => 2, :name => "steve"}] to include (include {:id => 3})
Diff:
@@ -1,2 +1,2 @@
-[(include {:id => 3})]
+[{:id=>6, :name=>"bob"}, {:id=>5, :name=>"jim"}, {:id=>2, :name=>"steve"}]
进一步阅读:
https://relishapp.com/rspec/rspec-expectations/docs/composing-matchers