.net 有没有一种方法可以在NUnit中无继承地在测试类之间共享断言?

.net 有没有一种方法可以在NUnit中无继承地在测试类之间共享断言?,.net,unit-testing,nunit,mspec,.net,Unit Testing,Nunit,Mspec,在MSpec中有一个整洁的特性,允许您在多个测试之间共享断言。他们被称为 行为定义了可重用的规范,这些规范封装了一组特定的, 你猜对了,行为学;然后,您就可以将这些规范包括在 显示特定行为的任何上下文 您可以将它们定义为带有断言的类(Itfields) 并将它们包括在测试类中,如 public class when_starting_a_car { Behaves_like<VehicleThatHasBeenStartedBehaviors> a_started_vehic

在MSpec中有一个整洁的特性,允许您在多个测试之间共享断言。他们被称为

行为定义了可重用的规范,这些规范封装了一组特定的, 你猜对了,行为学;然后,您就可以将这些规范包括在 显示特定行为的任何上下文

您可以将它们定义为带有断言的类(
It
fields)

并将它们包括在测试类中,如

public class when_starting_a_car
{
    Behaves_like<VehicleThatHasBeenStartedBehaviors> a_started_vehicle;
}
启动汽车时的
公共类
{
表现得像汽车一样;
}

如何使用NUnit实现同样的功能?

您可能需要了解一下这个概念


下面是一个SO,它描述了如何使用C#4.0实现这一点。您可以使用扩展方法“打包”特定于类型的断言:

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();
有没有一种方法可以在测试类之间共享断言而无需 努尼特的遗产

考虑到您只想共享断言,并且正在测试接口上的行为,您可以创建一些简单的东西:

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语法,我认为您可能需要实现它或者找到一些框架来为您实现它

编辑

阅读您对这个问题的评论,我意识到您可能希望重用测试方法,而不仅仅是断言。如果是这样的话,你可以写一封信。这听起来可能有点过分,但要由你来决定

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

目的

SuiteBuilder是用于从类型构建测试夹具的加载项。 NUnit本身使用SuiteBuilder来识别和构建TestFixture

使用您自己的套件生成器,您可以阅读一些行为类并组成您的装置

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

另一个简单的解决方案是在助手类中创建静态断言方法,您可以在每个适用的测试中调用该方法。例如:

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

你是说两个测试同时运行吗?或者进行两次测试的某种验证?您是否有使用此功能的代码示例或链接?我希望有一个包含断言的类包含在另一个类中。无法使用继承。例子。但是,我不认为这种方法对NUnit测试的开箱即用者有效。它使用基本反射查找用特定属性修饰的类/方法。这是一个动态的ish查找?
[TestFixture]
public class CarTest 
{
     [Test]
     public void TestCarStartsCorrectly() 
     {
         var car = new Car();
         car.Start();
         VehicleAssert.AssertCorrectlyStarted(car);
     }
}