tutorial - unit test project c#
MsTest ClassInitialize and Herencia (3)
Tengo una clase base para mis pruebas que se compone de la siguiente manera:
[TestClass]
public abstract class MyBaseTest
{
protected static string myField = "";
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
// static field initialization
myField = "new value";
}
}
Ahora estoy intentando crear una prueba nueva que herede de la base, con la siguiente firma:
[TestClass]
public class MyTest : MyBaseTest
{
[TestMethod]
public void BaseMethod_ShouldHave_FieldInitialized()
{
Assert.IsTrue(myField == "new value");
}
}
El ClassInitialize
nunca es llamado por las pruebas secundarias ... ¿Cuál es la forma real y correcta de usar la inicialización de prueba con herencia en MsTest?
Lamentablemente, no puede lograrlo de esa manera porque la clase ClassInitializeAttribute no se puede heredar.
Un atributo heredado puede ser utilizado por las subclases de las clases que lo usan. Como ClassInitializeAttribute
no se puede heredar, cuando se inicializa la clase MyTest
, no se puede ClassInitialize
método ClassInitialize
de la clase MyBaseTest
.
Intenta resolverlo de otra manera. Una forma menos eficiente es definir nuevamente el método ClassInitialize
en MyTest
y simplemente llamar al método base en lugar de duplicar el código.
Sabemos que una nueva instancia de la clase se construye para cada [TestMethod] en la clase a medida que se ejecuta. Se llamará al constructor sin parámetros de la clase base cada vez que esto ocurra. ¿No podría simplemente crear una variable estática en la clase base y probarla cuando se ejecute el constructor?
Esto le ayuda a no olvidar poner el código de inicialización en la subclase.
No estoy seguro de si hay algún inconveniente en este enfoque ...
Al igual que:
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()
{
}
}
Una posible solución es definir una nueva clase con AssemblyInitializeAttribute
lugar. Tiene un alcance diferente, obviamente, pero para mí satisface mis necesidades (preocupaciones transversales, que requieren exactamente los mismos ajustes para cada clase de prueba y método de prueba).
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyTests
{
[TestClass]
public sealed class TestAssemblyInitialize
{
[AssemblyInitialize]
public static void Initialize(TestContext context)
{
...
}
}
}