webentwicklung-frage-antwort-db.com.de

Jede Alternative für Microsoft Fakes in .NET Core?

Ich suche eine Alternative zu Microsoft Fakes in .NET Core. Ich weiß, dass es in .NET Core nicht mehr unterstützt wird. Ich verstehe einfach nicht warum nicht, ich denke es war eine gute Lösung in bestimmten Situationen.

Mein Problem ist, dass ich DateTime.Now verspotten möchte. Bisher konnten Sie dies mit dem folgenden Code tun:

System.Fakes.ShimDateTime.NowGet = () => 
{ 
   return new DateTime(2000, 1, 1); 
};

Weitere Informationen finden Sie in der Microsoft-Dokumentation unter dem Link: https://docs.Microsoft.com/en-us/visualstudio/test/using-shims-to-isolate-your-application-from-other -Baugruppen-für-Unit-Testing? view = vs-2017

Im Moment habe ich es gelöst, indem ich einen Wrapper für DateTime erstellt habe, der so aussieht:

/// <summary>
/// Used for getting DateTime.Now(), time is changeable for unit testing
/// </summary>
public static class SystemTime
{
   /// <summary> 
   /// Normally this is a pass-through to DateTime.Now, but it can be 
   /// overridden with SetDateTime( .. ) for testing or debugging.
   /// </summary>
   public static Func<DateTime> Now = () => DateTime.Now;

   /// <summary> 
   /// Set time to return when SystemTime.Now() is called.
   /// </summary>
   public static void SetDateTime(DateTime dateTimeNow)
   {
      Now = () =>  dateTimeNow;
   }

   /// <summary> 
   /// Resets SystemTime.Now() to return DateTime.Now.
   /// </summary>
   public static void ResetDateTime()
   {
       Now = () => DateTime.Now;
   }
}

Diese Lösung verdanke ich dem nächsten StackOverflow-Beitrag: Unit Testing: DateTime.Now

Mit dieser Lösung bin ich jedoch noch nicht zufrieden, da ich das Gefühl habe, dass ich meine Implementierung für meine Tests anpassen muss. Ich halte das nicht für wünschenswert.

Ich hoffe, jemand kann mir dabei helfen, vielen Dank im Voraus für die Mühe.

4
Undeadparade

Pose funktioniert gut dafür.

using Pose;

Shim dateTimeShim = Shim.Replace(() => DateTime.Now).With(() => new DateTime(2004, 4, 4));

// This block executes immediately
PoseContext.Isolate(() =>
{
    // All code that executes within this block
    // is isolated and shimmed methods are replaced

    // Outputs "4/4/04 12:00:00 AM"
    Console.WriteLine(DateTime.Now);

}, dateTimeShim);
5
Chris Gessler

Danke für all die Kommentare, das hat mir sicherlich geholfen. Ich habe meine Implementierung leicht modifiziert.

Die SystemTime-Klasse heißt jetzt DateTimeProvider und sieht folgendermaßen aus:

/// <summary>
/// Used for getting DateTime.Now(), time is changeable for unit testing
/// </summary>
public class DateTimeProvider : IDateTimeProvider
{
   /// <summary> 
   /// Normally this is a pass-through to DateTime.Now, but it can be 
   /// overridden with SetDateTime( .. ) for testing or debugging.
   /// </summary>
   private Func<DateTime> _now = () => DateTime.Now;
   public Func<DateTime> Now { get => _now; private set => _now = value; }

   /// <summary> 
   /// Set time to return when DateTimeProvider.Now() is called.
   /// </summary>
   public void SetDateTime(DateTime dateTimeNow)
   {
      Now = () =>  dateTimeNow;
   }

   /// <summary> 
   /// Resets DateTimeProvider.Now() to return DateTime.Now.
   /// </summary>
   public void ResetDateTime()
   {
       Now = () => DateTime.Now;
   }
}

Ich habe mich entschieden, den Setzer für jetzt privat () zu machen. Daher muss ein Entwickler die Methode SetDateTime () explizit verwenden, um die Uhrzeit zu ändern. Sie können auch eine Auto-Getter- und Setter-Eigenschaft verwenden.

Ich habe auch eine Schnittstelle hinzugefügt, damit die Klasse injiziert werden kann:

public interface IDateTimeProvider
{
    Func<DateTime> Now { get; }
    void SetDateTime(DateTime dateTimeNow);
    void ResetDateTime();
}

Ich hoffe, dass auch jemand anderes davon profitieren wird.

1
Undeadparade