Правильный способ удаления экземпляра IDisposable при использовании TestCaseSource NUnit - PullRequest
2 голосов
/ 02 августа 2020

У меня есть два немного разных варианта (TestsA и TestsB) параметризованных модульных тестов NUnit, которые используют TestCaseSource для передачи аргументов тестам. В каждом случае я передаю экземпляр класса, реализующего интерфейс IDisposable (в примерах я использую класс System.Windows.Forms.Control):

[TestFixture]
[Category("Tests A")]
public static class TestsA
{
    private static Control _CONTROL;

    [TearDown]
    public static void Teardown()
    {
        _CONTROL.Dispose();
    }

    private static class TestCases
    {
        public static IEnumerable<TestCaseData> TestCase1()
        {
            _CONTROL = new Control { Tag = 1 };
            yield return new TestCaseData(_CONTROL);
        }

        public static IEnumerable<TestCaseData> TestCase2()
        {
            _CONTROL = new Control { Tag = 2 };
            yield return new TestCaseData(_CONTROL);
        }
    }

    [TestCaseSource(typeof(TestCases), nameof(TestCases.TestCase1))]
    public static void Test1(Control control)
    {
        if (control == null)
            throw new ArgumentNullException(nameof(control));
        Assert.AreEqual(1, (int)control.Tag);
    }

    [TestCaseSource(typeof(TestCases), nameof(TestCases.TestCase2))]
    public static void Test2(Control control)
    {
        if (control == null)
            throw new ArgumentNullException(nameof(control));
        Assert.AreEqual(2, (int)control.Tag);
    }
}

[TestFixture]
[Category("Tests B")]
public static class TestsB
{
    private static class TestCases
    {
        public static IEnumerable<TestCaseData> TestCase1()
        {
            yield return new TestCaseData(new Control { Tag = 1 });
        }

        public static IEnumerable<TestCaseData> TestCase2()
        {
            yield return new TestCaseData(new Control { Tag = 2 });
        }
    }

    [TestCaseSource(typeof(TestCases), nameof(TestCases.TestCase1))]
    public static void Test1(Control control)
    {
        if (control == null)
            throw new ArgumentNullException(nameof(control));
        Assert.AreEqual(1, (int)control.Tag);
        control.Dispose();
    }

    [TestCaseSource(typeof(TestCases), nameof(TestCases.TestCase2))]
    public static void Test2(Control control)
    {
        if (control == null)
            throw new ArgumentNullException(nameof(control));
        Assert.AreEqual(2, (int)control.Tag);
        control.Dispose();
    }
}

Я пытаюсь найти правильный способ удаления экземпляров IDisposable. Тесты в классе TestsA используют метод TearDown для удаления. В TestsB я удаляю экземпляр сразу после Assert. Но независимо от того, как я это делаю, я получаю предупреждение CA2000. Описание предупреждения для TestsA и TestsB немного отличается:

TestsA: Предупреждение CA2000 В методе «TestsA.TestCases.TestCase1 ()» объект «new Control ()» не удаляется по всем путям исключения. Вызовите System.IDisposable.Dispose для объекта 'new Control ()' до того, как все ссылки на него будут вне области видимости.

TestsB: Предупреждение CA2000 В методе 'TestsB.TestCases.TestCase1 ()' вызовите System.IDisposable.Dispose для объекта 'new Control ()', прежде чем все ссылки на него будут вне области действия.

Мой вопрос: есть ли лучшая альтернатива для удаления объекта, переданного в тест NUnit через TestCaseSource, или я могу просто проигнорировать предупреждения?

...