Skip to content

Behaviors

Anthony Mastrean edited this page Aug 1, 2013 · 9 revisions

The Behaves_like<T> delegate and Behaviors attribute pair are used to create specifications for a common context among many "subjects" or implementations. The example below is liberally copied from James Gregory's excellent post on the topic.

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
{
    It should_have_a_running_engine = () => Subject.IsEngineRunning.ShouldBeTrue();
    It should_be_idling = () => Subject.RevCount.ShouldBeBetween(0, 1000);

    protected static IVehicle Subject;
}

We test two implementations of the Subject, a motorcycle and a car, in the same context -- starting the engine. 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")]
public class When_the_car_is_started
{
    Establish = () => Subject = new Car();
    Because of = () => Subject.StartEngine();
    Behaves_like<A_vehicle_that_has_been_started> a_vehicle_that_has_been_started;

    protected static Car Subject;
}

[Subject("Starting")]
public class When_the_motorcycle_is_started
{
    Establish = () => Subject = new Motorcycle();
    Because of = () => Subject.StartEngine();
    Behaves_like<A_vehicle_that_has_been_started> a_vehicle_that_has_been_started;

    protected static Motorcycle Subject;
}

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

⌂ 换网址