-
Notifications
You must be signed in to change notification settings - Fork 5
Expectations
Expectations, also called assertions, are a core component of testing. They describe the criteria that must be met for the test to pass.
In Spectator, an expectation is the following:
expect(actual).to eq(expected)
The value being tested is actual
, and the correct value (needed to pass the test) is expected
.
Breaking it apart:
# VVVVVVVVVVVV matcher
expect(actual).to eq(expected)
# ^^^^^^^^^^^^ expectation partial
There are two parts that make up an expectation - the partial and the matcher. The partial describes what is being tested. This is the value or block of code being inspected. The matcher operates on the partial. It determines whether it is satisfied with the actual value. There are many types of matchers, visit the matchers page for a full list.
A partial should be called with to
or to_not
.
If it is grammatically more correct, not_to
can be used as well.
The argument passed to to
or to_not
is a matcher.
Currently, there are two types of expectation partials. There may be more added in future versions to support complex matchers. The first, and simplest, is a value partial. The value partial takes a single value and checks it against the matcher.
expect("foobar").to eq("foobar")
The other type of partial is a block partial. This takes a block and checks it against the matcher.
expect { raise "oops" }.to raise_error(/oops/i)
Not all matchers support block partials. That's not an issue, however. Matchers that expect a value will instead check the value returned by the block. For instance:
expect { 1 + 2 }.to eq(3)
Works as expected. The block is evaluated and the return value is used by the matcher.
The short-hand block syntax can be used in partials. For instance:
expect(&.odd?).to be_true
expands to:
expect { subject.odd? }.to be_true
When using the short-hand syntax, the subject is always used.
If you need to test an expectation after the example finishes, check out [deferred expectations](Deferred Expectations).
The actual value can be cast when using specific matchers. This can strip types from a union if the expectation is satisfied.
value = 42.as(Int32 | String | Symbol)
typeof(value) # => (Int32 | String | Symbol)
integer = expect(value).to be_a(Int32) # Reduces the type of `integer` to just `Int32`.
typeof(integer) # => Int32
integer = expect(value).to_not be_a(String) # Strips `String` from the type.
typeof(integer) # => (Int32 | Symbol)
value = 42.as(Int32?)
typeof(value) # => (Int32 | Nil)
integer = expect(value).to_not be_nil # Strips nil from the type.
typeof(integer) # => Int32