Ich habe mit dem Konzept herumgespielt, die statischen Methoden zu überarbeiten, um einen Delegaten aufzurufen, den Sie zu Testzwecken extern festlegen können.
Dies würde kein Testframework verwenden und wäre eine vollständig maßgeschneiderte Lösung. Der Refactor hat jedoch keinen Einfluss auf die Signatur Ihres Anrufers und wäre daher relativ sicher.
Damit dies funktioniert, müssen Sie Zugriff auf die statische Methode haben, damit sie für externe Bibliotheken wie z System.DateTime
.
Hier ist ein Beispiel, mit dem ich gespielt habe, wo ich einige statische Methoden erstellt habe, eine mit einem Rückgabetyp, der zwei Parameter akzeptiert, und eine generische, die keinen Rückgabetyp hat.
Die statische Hauptklasse:
public static class LegacyStaticClass
{
static LegacyStaticClass()
{
ResetDelegates();
}
public static void ResetDelegates()
{
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);
}
Die Unit-Tests (xUnit und 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();
}
}