web-dev-qa-db-ja.com

.NET CoreのMicrosoft Fakesに代わるものはありますか?

.NET CoreのMicrosoft Fakesに代わるものを探しています。 .NET Coreではサポートされなくなったことを知っています。なぜだかわからないのですが、ある状況では良い解決策だったと思います。

私の問題は、DateTime.Nowをモックしたいことです。以前は、次のコードでこれを行うことができました。

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

これは、Microsoftのドキュメントで説明されています。詳細については、リンクを参照してください。 https://docs.Microsoft.com/en-us/visualstudio/test/using-shims-to-isolate-your-application-from -other-assemblies-for-unit-testing?view = vs-2017

今のところ、DateTimeのラッパーを作成して解決しました。

/// <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;
   }
}

私はこのソリューションを次のStackOverflowポストに借りています: nit Testing:DateTime.Now

しかし、テストのために実装を調整する必要があると感じているため、このソリューションにはまだ満足していません。これは望ましいとは思いません。

誰かがこれを手伝ってくれることを願っています。

14
Undeadparade

Pose はこれに適しています。

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);
7
Chris Gessler

すべてのコメントをありがとう、それは確かに私を助けました。実装を少し変更しました。

SystemTimeクラスはDateTimeProviderと呼ばれ、次のようになります。

/// <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;
   }
}

Now()のセッターをプライベートにすることを選択しました。その結果、開発者は明示的にメソッドSetDateTime()を使用して時刻を変更する必要があります。自動ゲッターおよびセッタープロパティの使用を選択することもできます。

また、クラスを挿入できるようにインターフェイスを追加しました。

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

他の誰かもこれから恩恵を受けることを願っています。

2
Undeadparade