2010-04-28 14 views
17

Estoy configurando algunas pruebas de unidad basadas en MSTest. Para hacer mi vida más fácil, quiero usar una clase base que maneje la configuración genérica y la tara que requieren todas mis pruebas. Mi clase base es el siguiente:Uso de herencia en MSTest

[TestClass] 
public class DBTestBase { 
    public TestContext TestContext { get; set; } 

    [ClassInitialize()] 
    public static void MyClassInitialize(TestContext testContext) { 
     var config = new XmlConfigurationSource("ARconfig_test.xml"); 
     ActiveRecordStarter.Initialize(Assembly.Load("LocalModels"), config); 
    } 

    [TestInitialize()] 
    public void MyTestInitialize() { 
     ActiveRecordStarter.CreateSchema(); 
     Before_each_test(); 
    } 

    protected virtual void Before_each_test() { } 

    [TestCleanup()] 
    public void MyTestCleanup() { 
     After_each_test(); 
    } 

    protected virtual void After_each_test() { } 
} 

mi clase de prueba real se ve así:

[TestClass] 
public class question_tests : DBTestBase { 

    private void CreateInitialData() { 
     var question = new Question() 
          { 
           Name = "Test Question", 
           Description = "This is a simple test question" 
          }; 
     question.Create(); 
    } 

    protected override void Before_each_test() { 
     base.Before_each_test(); 
     CreateInitialData(); 
    } 

    [TestMethod] 
    public void test_fetching() { 
     var q = Question.FindAll(); 
     Assert.AreEqual("Test Question", q[0].Name, "Incorrect name."); 
    } 
} 

La función TestInitialize funciona como se esperaba. Pero la función ClassInitialize nunca se ejecuta. Que se ejecuta si añado lo siguiente para mi clase de niño:

[ClassInitialize()] 
    public static void t(TestContext testContext) { 
     MyClassInitialize(testContext); 
    } 

¿Es posible conseguir mi clase base para ejecutar la función sin hacer referencia a que en mi clase hija inicializar?

+2

Demasiado hacky como respuesta: intente utilizar un constructor estático en la clase base. – roufamatic

+0

Terminé usando AssemblyInitialize(). No es exactamente lo que quería, pero supongo que MSTest no lo hace. @Roufamatic, su respuesta probablemente sea la única. Si lo publicas, lo aceptaré. – oillio

Respuesta

4

Confirma que esto también fue un problema para mí. Utilicé un constructor en la base y un destructor para la limpieza

+1

El problema es que no se garantiza que el finalizador se ejecute en un momento determinista. Por ejemplo, en mis pruebas, quiero suplantar a un usuario dado, pero una vez que terminen mis pruebas, deshaga la suplantación. Eso no funcionará con un finalizador, porque lo más probable es que varias de mis otras pruebas se ejecutarán antes de que se ejecute. –

+4

El problema con el constructor es que funciona igual que TestInitialize. Se ejecutará en todas las pruebas. – bygrace

+0

No hay Finalizador aquí, solo el uso de TestCleanup() - GRAN diferencia. El comportamiento y la ejecución de TestCleanup() es determinista y está bien definido. –

8

El método ClassInitialize se ejecuta si y solo si la "clase" en cuestión contiene al menos un TestMethod y se selecciona al menos un TestMethod de la clase para la ejecución.

+0

Bueno, esa es una manera bastante tonta de codificarlo. TestInitialize y TestCleanup no funcionan de esa manera ... – oillio

+0

estuvieron de acuerdo - pero esa es la forma en que es :-( – Ambuj

+0

he añadido esto a mi código: [ClassInitialize] pública nueva ClassSetup static void (contexto TestContext) { TestBase .ClassSetup (context); } –

0
[TestClass] 
public class question_tests : DBTestBase { 
... 
    [TestCleanup()] 
    public void TestCleanup() 
    { 
     base.MyTestCleanup(); 
    }