Skip to content

Behaviors

Robert Coltheart edited this page Sep 11, 2020 · 9 revisions
⚠️ Note that the usage of behaviors is discouraged and the feature is only maintained for backward compatibility. Please see Best Practices for guidance.

The Behaves_like<T> delegate and Behaviors attribute pair are used to create specifications for a common context among many "subjects" or implementations.

A class is marked with the Behaviors attribute and contains all of the common It statements. You see the subject, an IVehicle, is declared as a protected, static field. Base concrete types should work as well. You should name the class in regular PascalCase.

[Behaviors]
public class AVehicleThatHasBeenStarted
{
    protected static IVehicle Subject;

    It should_have_a_running_engine = () =>
        Subject.IsEngineRunning.ShouldBeTrue();

    It should_be_idling = () =>
        Subject.RevCount.ShouldBeGreaterThan(0);
}

We can test two implementations of the Subject, a motorcycle and a car, in the same context. Notice that each subject is protected & static and must be named identically. The Behaves_like field must not be assigned a value and should be named after the behaviors class, but in snake_case.

[Subject("Starting")]
class When_the_car_is_started
{
    protected static Car Subject;

    Establish context = () =>
        Subject = new Car();

    Because of = () =>
        Subject.StartEngine();

    Behaves_like<AVehicleThatHasBeenStarted> a_vehicle_that_has_been_started;
}

[Subject("Starting")]
class When_the_motorcycle_is_started
{
    protected static Motorcycle Subject;

    Establish context = () =>
        Subject = new Motorcycle();

    Because of = () =>
        Subject.StartEngine();

    Behaves_like<AVehicleThatHasBeenStarted> a_vehicle_that_has_been_started;
}

The names of the individual It statements in the behaviors class will be printed in your test output, not the name of the behaviors class.

Clone this wiki locally