Подтвердить что ты не робот

MsTest ClassInitialize и Inheritance

У меня есть базовый класс для моих тестов, который составлен следующим образом:

[TestClass]
public abstract class MyBaseTest
{
   protected static string myField = "";

   [ClassInitialize]
   public static void ClassInitialize(TestContext context)
   {
       // static field initialization
       myField = "new value";
   }
}

Теперь я пытаюсь создать новый тест, который наследуется от базы, со следующей сигнатурой:

[TestClass]
public class MyTest : MyBaseTest
{
   [TestMethod]
   public void BaseMethod_ShouldHave_FieldInitialized()
   {
       Assert.IsTrue(myField == "new value");
   }
}

ClassInitialize никогда не вызывается дочерними тестами... Что такое реальный и правильный способ использования тестовой инициализации с наследованием на MsTest?

4b9b3361

Ответ 1

К сожалению, вы не можете достичь этого, потому что ClassInitializeAttribute Class не может быть унаследован.

Унаследованный атрибут может использоваться подклассами классов, которые его используют. Поскольку ClassInitializeAttribute не может быть унаследован, когда класс MyTest инициализирован, метод ClassInitialize из класса MyBaseTest не может быть вызван.

Попробуйте решить это по-другому. Менее эффективным способом является определение метода ClassInitialize в MyTest и просто вызов базового метода вместо дублирования кода.

Ответ 2

Потенциальным обходным путем является определение нового класса с AssemblyInitializeAttribute. Очевидно, что он имеет различную область видимости, но для меня он отвечает моим потребностям (сквозные проблемы, которые, как раз так, требуют одинаковых настроек для каждого тестового класса и метода тестирования.)

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MyTests
{
  [TestClass]
  public sealed class TestAssemblyInitialize
  {
    [AssemblyInitialize]
    public static void Initialize(TestContext context)
    {
      ...
    }
  }
}

Ответ 3

Мы знаем, что новый экземпляр класса создается для каждого [TestMethod] в классе по мере его запуска. Каждый раз, когда это происходит, будет вызываться конструктор без параметров. Не могли бы вы просто создать статическую переменную в базовом классе и проверить ее при запуске конструктора?

Это поможет вам не забыть поместить код инициализации в подкласс.

Не уверен, есть ли недостаток в этом подходе...

Так же:

public class TestBase
{
    private static bool _isInitialized = false;
    public TestBase()
    {
        if (!_isInitialized)
        {
            TestClassInitialize();
            _isInitialized = true;
        }
    }

    public void TestClassInitialize()
    {
        // Do one-time init stuff
    }
}
public class SalesOrderTotals_Test : TestBase
{
    [TestMethod]
    public void TotalsCalulateWhenThereIsNoSalesTax()
    {
    }
    [TestMethod]
    public void TotalsCalulateWhenThereIsSalesTax()
    {
    }
}

Ответ 4

Использовать статический конструктор для базового класса? Это выполнено только один раз, по замыслу, и у него нет странного ограничения на наследование, как ClassInitializeAttribute.