RSpec: ". not_to include" behaves like ".to exclude"

RSpec is smart when using the include-matcher in combination with .not_to. One could assume that

.not_to include(3, 4, 5)

evaluates to:

NOT( .to include(3, 4, 5) )

However, it behaves like:

.to (NOT include(3) && NOT include(4) && NOT include(5) )

Warning

Using .not_to in combination with the include-matcher doesn't logically negate the final truth value. It instead negates the individual include-expectations for each argument.

Proof

describe 'RSpec' do
  it "doesn't use logical negation for include, exhibit A" do
    expect([1, 2, 3]).to include(3, 4, 5)
  end

  it "doesn't use logical negation for include, exhibit B" do
    expect([1, 2, 3]).not_to include(3, 4, 5)
  end
end

Exhibit A fails with:

expected [1, 2, 3] to include 4 and 5

Exhibit B fails with:

expected [1, 2, 3] not to include 3

Applications

Tip

This can be used to test for exclusion of multiple values all at once.

Klaus Weidinger Over 2 years ago