有没有办法在NUnit中没有继承的情况下在测试类之间共享断言?

时间:2013-01-07 08:33:55

标签: .net unit-testing nunit mspec

在MSpec中,有一个简洁的功能,允许您在多个测试之间共享断言。他们被称为"behaviors"

  

行为定义封装特定集合的可重用规范,   你猜对了,行为;然后你就可以将这些规格包括在内了   任何表现出特定行为的背景。

您可以将它们定义为带有断言(It字段)

的类
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);
}

并将它们包含在您的测试类中,如

public class when_starting_a_car
{
    Behaves_like<VehicleThatHasBeenStartedBehaviors> a_started_vehicle;
}

如何使用NUnit完成相同的操作?

4 个答案:

答案 0 :(得分:4)

您可以使用扩展方法“打包”特定于类型的断言:

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);
    }
}

在测试方法上使用它:

testVehicle.ShouldBeStarted();

答案 1 :(得分:3)

  

有没有办法在没有测试类的情况下共享断言   在NUnit中继承?

考虑到你只是想分享断言而你正在测试接口上的行为,你可以创建一些简单的东西:

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();
    }
}

但是,如果您想专门使用MSpec语法,我认为您可能必须实现它或找到一些适合您的框架。

修改

阅读你对这个问题的评论我意识到你可能想要重用测试方法,而不仅仅是断言。如果是这种情况,您可以写一个customized addin for NUnit。这可能听起来有点矫枉过正,但由你来决定。

我的起点将编写自定义的SuiteBuilder对象:

  

<强>目的

     

SuiteBuilder是一个用于从类型构建测试夹具的插件。   NUnit本身使用SuiteBuilder来识别和构建TestFixtures。

使用您自己的套件构建器,您可以阅读一些行为类并构建您的夹具。

[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.
    }
}

答案 2 :(得分:1)

您可能希望了解Mixin概念。

这是一个SO answer,描述了如何使用C#4.0实现这一目标

答案 3 :(得分:1)

另一个简单的解决方案是在Helper类中创建静态Assertion方法,您可以在每个适用的测试中调用它们。例如:

public static class VehicleAssert 
{
    public void AssertCorrectlyStarted(IVehicle car) 
    {
         vehicle.IsEngineRunning.ShouldBeTrue();
         vehicle.RevCount.ShouldBeBetween(0, 1000); 
    }
 }   

然后在每个testfixture中使用它:

[TestFixture]
public class CarTest 
{
     [Test]
     public void TestCarStartsCorrectly() 
     {
         var car = new Car();
         car.Start();
         VehicleAssert.AssertCorrectlyStarted(car);
     }
}