He estado jugando con un concepto de refactorización de los métodos estáticos para invocar a un delegado que puede establecer externamente para fines de prueba.
Esto no utilizaría ningún marco de prueba y sería una solución completamente a medida, sin embargo, el refactor no influirá en la firma de la persona que llama y por lo tanto sería relativamente seguro.
Para que esto funcione, debe tener acceso al método estático, por lo que no funcionaría para ninguna biblioteca externa como System.DateTime
.
Heres un ejemplo en el que he estado jugando donde he creado un par de métodos estáticos, uno con un tipo de devolución que toma dos parámetros y un genérico que no tiene tipo de devolución.
La principal clase estática:
public static class LegacyStaticClass
{
// A static constructor sets up all the delegates so production keeps working as usual
static LegacyStaticClass()
{
ResetDelegates();
}
public static void ResetDelegates()
{
// All the logic that used to be in the body of the static method goes into the delegates instead.
ThrowMeDelegate = input => throw input;
SumDelegate = (a, b) => a + b;
}
public static Action<Exception> ThrowMeDelegate;
public static Func<int, int, int> SumDelegate;
public static void ThrowMe<TException>() where TException : Exception, new()
=> ThrowMeDelegate(new TException());
public static int Sum(int a, int b)
=> SumDelegate(a, b);
}
Las pruebas unitarias (xUnit y Shouldly)
public class Class1Tests : IDisposable
{
[Fact]
public void ThrowMe_NoMocking_Throws()
{
Should.Throw<Exception>(() => LegacyStaticClass.ThrowMe<Exception>());
}
[Fact]
public void ThrowMe_EmptyMocking_DoesNotThrow()
{
LegacyStaticClass.ThrowMeDelegate = input => { };
LegacyStaticClass.ThrowMe<Exception>();
true.ShouldBeTrue();
}
[Fact]
public void Sum_NoMocking_AddsValues()
{
LegacyStaticClass.Sum(5, 6).ShouldBe(11);
}
[Fact]
public void Sum_MockingReturnValue_ReturnsMockedValue()
{
LegacyStaticClass.SumDelegate = (a, b) => 6;
LegacyStaticClass.Sum(5, 6).ShouldBe(6);
}
public void Dispose()
{
LegacyStaticClass.ResetDelegates();
}
}
como una actualización de este. Moles ahora se llama Fakes y está integrado en Visual Studio 2012: http://msdn.microsoft.com/en-us/library/hh549175.aspx – gscragg
En Moles puede verificar si se ha llamado a un método simplemente agregando una variable booleana y al establecerlo dentro de la función stub también se pueden verificar todos los parámetros en la llamada con este workarround. – mart
Hola Jeco ... Tengo una idea de tu respuesta anterior. ¿Podría responder una pregunta en http://stackoverflow.com/questions/27621085/moles-shims-frameworks-other-than-introduced-by-microsoft –