In MSpec there is a neat feature that allows you share assertions between multiple tests. They're called "behaviors"
Behaviours define reusable specs that encapsulate a particular set of, you guessed it, behaviours; you’re then able to include these specs in any context that exhibits a particular behaviour.
You define them as a class with assertions (It
fields)
public class VehicleThatHasBeenStartedBehaviors
{
protected static IVehicle vehicle;
It should_have_a_running_engine = () => vehicle.IsEngineRunning.ShouldBeTrue();
It should_be_idling = () => vehicle.RevCount.ShouldBeBetween(0, 1000);
}
and include them in your test class like
public class when_starting_a_car
{
Behaves_like<VehicleThatHasBeenStartedBehaviors> a_started_vehicle;
}
How can I accomplish the same with NUnit?
You can use extension methods to "package" your type-specific assertions:
public static class VehicleAssertions {
public static void ShouldBeStarted(this IVehicle vehicle) {
// TODO: change these to NUnit assertions
vehicle.IsEngineRunning.ShouldBeTrue();
vehicle.RevCount.ShouldBeBetween(0, 1000);
}
}
Use it on a test method:
testVehicle.ShouldBeStarted();
Is there a way to share assertions among test classes without inheritance in NUnit?
Considering you just want to share assertions and you're testing for behaviors on interfaces, you could just create something simple:
public interface IBehavior
{
void Check();
}
public class VehicleThatHasBeenStartedBehaviors : IBehavior
{
protected IVehicle vehicle;
public VehicleThatHasBeenStartedBehaviors(IVehicle vehicle)
{
this.vehicle = vehicle;
}
public void Check()
{
Assert.That(vehicle.IsEngineRunning, Is.True);
Assert.That(vehicle.RevCount, Is.LessThanOrEqualTo(1000));
Assert.That(vehicle.RevCount, Is.GreaterThanOrEqualTo(0));
}
}
[TestFixture]
public class when_starting_a_car
{
protected Car car;
[SetUp]
public void SetUp()
{
car = new Car();
}
[Test]
public void behaves_like_a_started_vehicle()
{
new VehicleThatHasBeenStartedBehaviors(car).Check();
}
}
BUT, if you want to specifically use MSpec syntax, I think you may have to implement it or find some framework that does it for you.
EDIT
Reading your comments on the question I realized you may be wanting to reuse test methods, and not simply assertions. If that's the case, you could write a customized addin for NUnit. That may sound a little overkill, but it's up to you to decide.
My starting point would be writing a customized SuiteBuilder object:
Purpose
A SuiteBuilder is an addin used to build a test fixture from a type. NUnit itself uses a SuiteBuilder to recognize and build TestFixtures.
Using your own suite builder you could read some behavior classes and compose your fixture.
[NUnitAddin]
public class TestCompositionAddinProvider : IAddin
{
#region IAddin Members
public bool Install(IExtensionHost host)
{
IExtensionPoint builders = host.GetExtensionPoint("SuiteBuilders");
if (builders == null)
return false;
builders.Install(new TestCompositionSuiteBuilder());
return true;
}
#endregion
}
public class TestCompositionSuiteBuilder : ISuiteBuilder
{
#region ISuiteBuilder Members
public bool CanBuildFrom(Type type)
{
//TODO: Create validation logic
return true;
}
public NUnit.Core.Test BuildFrom(Type type)
{
if (CanBuildFrom(type))
return new ComposedSuiteExtension(type);
return null;
}
#endregion
}
public class ComposedSuiteExtension : TestSuite
{
public ComposedSuiteExtension(Type fixtureType)
: base(fixtureType)
{
//TODO: Create logic to add test methods from various behaviors.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With