10

MSpec には、複数のテスト間でアサーションを共有できる便利な機能があります。それらは「行動」と呼ばれます。

動作は、ご想像のとおり、特定の動作のセットをカプセル化する再利用可能な仕様を定義します。その後、特定の動作を示す任意のコンテキストにこれらの仕様を含めることができます。

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

4 に答える 4

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();
于 2013-01-10T15:12:40.777 に答える
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 構文を使用したい場合は、それを実装するか、それを行うフレームワークを見つける必要があると思います。

編集

質問に対するあなたのコメントを読んで、単にアサーションではなく、テスト メソッドを再利用したいと考えていることに気付きました。その場合は、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.
    }
}
于 2013-01-16T12:45:32.037 に答える
1

Mixinの概念を確認することをお勧めします。

これは、C#4.0でこれを達成する方法を説明するSOの回答です

于 2013-01-08T12:53:51.453 に答える
1

別の簡単な解決策は、該当する各テストで呼び出すヘルパー クラスに静的アサーション メソッドを作成することです。たとえば、次のようにします。

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

次に、各テストフィクスチャで次のように使用します。

[TestFixture]
public class CarTest 
{
     [Test]
     public void TestCarStartsCorrectly() 
     {
         var car = new Car();
         car.Start();
         VehicleAssert.AssertCorrectlyStarted(car);
     }
}
于 2013-01-16T13:15:05.597 に答える