or9ob
or9ob

Reputation: 2392

RSpec magic for testing an array's none? method?

I have an Array/Enumerable where each entity is a Hash. Using RSpec what is the most idiomatic way to test for "none of the entries in the enumerable should have a key called 'body'"?

I can do something like:

array.none? {|thing| thing.key? 'body'}.should be_true

or

array.should be_none {|thing| thing.key? 'body'}

...but there must be a more RSpec-way of doing this, correct?

I can't seem to find an appropriate built-in matcher. Is the answer a custom matcher?

Upvotes: 2

Views: 868

Answers (2)

lime
lime

Reputation: 7101

Another option would be turning the be_none statement around with be_any:

responses.should_not be_any { |response| response.key? 'body' }

I would assume that the result is equivalent as any? is the negation of none?.

It's mostly a question of which option you feel is the most intuitive to read and, as EnabrenTane mentions, if you think the error messages are helpful enough.

Upvotes: 0

EnabrenTane
EnabrenTane

Reputation: 7466

I would use responses.should be_none { |response| response.key? 'body' }

Between the two you gave. This would be slightly more helpful with an error like

"Expected none? to return true"

where as your first example would say something like

"expected False:false class to be true"

The third option I can see would be something like

 keys = responses.map { |response| response.keys }.flatten.uniq
 keys.should_not include "body"

This would give an error like

expected ["foo", "bar", "body"] not to include "body"

Other than that, looking at https://www.relishapp.com/rspec/rspec-expectations/v/2-11/docs/built-in-matchers/satisfy-matcher

you could try

responses.should satisfy { |response| not response.keys.include? "body" }

Upvotes: 1

Related Questions