web-dev-qa-db-ja.com

名前空間ごとではなくクラスごとに1回実行されるSetUpFixtureを使用する方法はありますか?

シナリオ
まず、私はテストに慣れていないので、我慢してください。私のテストプロジェクトの中に、Controllersフォルダーがあります。 Controllersフォルダーには、ControllerATest.cs、ControllerBTest.cs、およびControllerCTest.csが含まれる場合があります。私の名前空間はフォルダ構造と一致しているため、すべてが名前空間MyProject.Tests.Controllersを共有しています。

NUnit SetUpFixture Documentation で読んだことから、この名前空間内の[SetUpFixture]は、名前空間全体に対して一度実行されます。つまり、すべてのコントローラーテストを一度に実行すると、SetUpFixtureは1回だけ実行されます。

問題
前述したように、各コントローラーテストは名前空間を共有します。 SetUpFixturesは名前空間全体に適用されます。各コントローラーにownSetUpFixtureを持たせたい場合はどうなりますか?これは、SetUpFixturesが名前空間全体に適用される場合の問題です。私が欲しいのは、テストごとではなく、一度実行するものです。 SetUpFixtureのSetUp内で行うことの1つは、コントローラーをインスタンス化することです。確かに、SetUpFixtureで3つすべてのコントローラーをインスタンス化することはできましたが、ControllerCだけをテストしていると、これは醜いようです。それは本当にきれいに見えません。したがって、ControllerCTestsなどのクラスにonlyを適用するSetUpFixtureが必要です。

私が読んだことから、この特定の機能はNUnitでは不可能のようです。そして、NUnitでそれが不可能な場合、それは一般的なシナリオではないと思います。そして、それが一般的なシナリオでない場合、私は何か間違ったことをしています。私の質問は、何ですか?たぶん私のテスト構造がオフになっていて、変更する必要があります。それともそれはNUnitで可能です

コード
私の望ましい構造の例:

namespace MyProject.Tests.Controllers
{
public class ControllerATests
{
    private static IMyProjectRepository _fakeRepository;
    private static ControllerA _controllerA;

    [SetUpFixture]
    public class before_tests_run
    {
        [SetUp]
        public void ControllerASetup()
        {
            _fakeRepository = FakeRepository.Create();

            _controllerA = new ControllerA(_fakeRepository);
        }
    }

    [TestFixture]
    public class when_ControllerA_index_get_action_executes
    {
        [Test]
        public void it_does_something()
        {
            //
        }

        [Test]
        public void it_does_something_else()
        {
            //
        }
    }
}

public class ControllerBTests
{
    private static IMyProjectRepository _fakeRepository;
    private static ControllerB _controllerB;

    [SetUpFixture]
    public class before_tests_run
    {
        [SetUp]
        public void ControllerBSetup()
        {
            _fakeRepository = FakeRepository.Create();

            _controllerB = new ControllerB(_fakeRepository);
        }
    }

    [TestFixture]
    public class when_ControllerB_index_get_action_executes
    {
        [Test]
        public void it_does_something()
        {
            //
        }

        [Test]
        public void it_does_something_else()
        {
            //
        }
    }
}
}    

私が試したもの

  • 各.csファイルを独自のフォルダーに移動して、異なる名前空間を持つようにします。技術的にはこれで問題が解決します。サブフォルダーがたくさんあり、それぞれにアイテムが1つしかないのは少し見苦しいようです。醜く、私の親プロジェクトの構造と一致しなくなります。しかし-多分これは行く方法です。
  • SetUpFixtureSetUpでコントローラーをインスタンス化せず、代わりにTestFixtureSetUpでそれを実行して、新しいコントローラーがすべてインスタンス化されるようにしますクラスまたは名前空間ごとに1回ではなく、テスト(例:5つのテスト= 5つの個別のインスタンス)。 1つのインスタンスを作成するだけで済むように思えますが、そうすべきです。

提案?

23
EF0

コントローラクラスのメソッドで TestFixtureSetUpAttribute を使用します。

[TestFixture]
public class when_ControllerA_index_get_action_executes
{
    [TestFixtureSetUp]
    public void FixtureSetUp()
    {
        // this code runs once no matter how many tests are in this class
    }

    [Test]
    public void it_does_something()
    {
        // ...
    }
}

ドキュメントから:

この属性はTestFixture内で使用され、フィクスチャでテストを実行する前に一度実行される単一の関数セットを提供します。

ここで、「TestFixture」はclassと同義です。

21
Patrick Quirk

NUnit3.4.1以降の場合は、 OneTimeSetUp を使用します。

[TestFixture]
public class MyTest
{
    [OneTimeSetUp]
    public void Setup()
    {
        // one time setup code for this class
    }
}

ちなみに、 TestFixtureSetUp は廃止されました。

46
Tyler Long