Assertions features

Specter allows you to specify a range of behaviors and properties your code must have. You do this by using the Must extension method (although thanks to some macro magic it looks like a property).

Here is an example of Must in action:

specify person.Age.Must.Equal(42)

Here we are specifying that the Age property of the person must equal 42. To assert the opposite you can insert a Not:

specify person.Age.Must.Not.Equal(42)

Specter provides different sets of assertions for various .NET base types. These include:

Numeric Assertions

Assertion Description
Equal(expected) Actual value must equal expected value
BeLessThan(expected) Actual value must be less than expected value
BeLessThanOrEqual(expected) Actual value must be less than or equal expected value
BeGreaterThan(expected) Actual value must be greater than expected value
BeGreaterThanOrEqual(expected) Actual value must be greater than or equal expected value

Of course typing BeGreaterThanOrEqual everywhere can get annoying! So Specter provides handy operator overloads.
person.Age.Must == 42
person.Age.Must != 42
person.Age.Must.Be < 42
person.Age.Must.Be <= 42
person.Age.Must.Be > 42
person.Age.Must.Be >= 42
(Note the addition of Be after Must. Whilst not strictly needed, it makes the code that bit more readable.)

Floating point values (single and double) are not always equatable due to the nature of binary floating point arithmetic. It is therefore safer to assert that a floating point value is close to a known value with a given tolerance.

Specter has the following syntax to assert this:
specify myDouble.Must.BeWithin(0.00001).Of(42)
If you want the tolerance to be as small as possible use double.epsilon or single.epsilon.

String Assertions

Assertion Description
Equal(expectedString) Actual value must equal the expected string
BeEmpty() Actual value must be an empty string (but not null)
StartWith(expectedString) Actual value must start with the expected string
EndWith(expectedString) Actual value must end with the expected string
Contain(expectedString) Actual value must contain the expected string
Match(regularExpression) Actual must match the expected regular expression

If you want to use case-insenstive assertions then use the IgnoringCase property:
specify person.Name.Must.IgnoringCase.Equal("andrew")

As for numeric values, comparison assertions are possible using BeLessThan, BeLessThanOrEqual, BeGreaterThan and BeGreaterThanOrEqual. Operator overloads also exist for these.
For example, specify person.ID.Must.Be <= "zzz".

Specter also overloads the Boo regular expression match operator.
For example, specify person.Name.Must =~ /[A-Z][a-z]+/

Boolean Assertions

Applies to value of type bool (System.Boolean).

Assertion Description
BeTrue() Actual value must be true.
BeFalse() Actual value must be false.

Object Assertions

Object assertions apply to any .NET reference type (i.e. not value types, like int and double).

Assertion Description
BeNull() Object reference must be null.
ReferentiallyEqual(expected) Actual object must be a reference to the expected object.
BeInstanceOf(expectedType) Actual object must be an exact instance of the expected type (not a subclass).
BeKindOf(expectedType) Actual object must be of the expected type (including subclass, or implementor in case of an interface).

Enumerable Assertions

Applies to anything implementing System.IEnumerable.

Assertion Description
Contain(expectedItem) Enumeration must contain the expected item.
BeEmpty() Enumeration must contain no items.
AllSatisfy(predicate) All items in the enumeration must satisfy the given predicate.
An empty enumeration will not cause this to fail.
example specify people.Must.AllSatisfy({ p | return p.Name == "andrew" })
SomeSatisfy(predicate) One or more items in the enumeration must satisfy the given predicate.
An empty enumeration will cause this to fail.
example specify people.Must.SomeSatisfy({ p | return p.Name == "andrew" })
Equal(expectedEnumeration) Each item in the actual enumeration must equal its respective item in the expected enumeration (and therefore both enumerations are the same size too).

List Assertions

These apply to anything that implements System.IList. Therefore the assertion available for enumerable types also apply (but are re-implemented using specific IList members, such as Count and Contains).

Delegate Assertions

Methods are first-class data types in Boo. Specter makes use of this fact by allowing you to assert whether or not a piece of code throws an exception when called.

Assertion Description
Throw() This will expect some kind of exception to be thrown when the anonymous method is called.
example specify { person.Save() }.Must.Throw()
Throw(exceptionType) This will expect an exception of exact type exceptionType to be thrown when the anonymous method is called.
example specify { person.Save() }.Must.Throw(typeof(IllegalOperationException))
ThrowKindOf(exceptionType) This will expect an exception of type exceptionType (including subclass, or implementor in cae of an interface) to be thrown when the anonymous method is called.
example specify { person.Save(null) }.Must.ThrowKindOf(typeof(ArgumentException))

Satisfy Assertion

The Satisfy assertion applies to any .NET type. It allows you to provide your own arbitrary predicate to test the actual value.
For example: specify person.Must.Satisfy({p as person | MyFancyLookUp(p.Name) == 42 })

Want more ?

Look at the other documentation links on the homepage.