web-dev-qa-db-ja.com

moqで静的プロパティをモックする

moq を使用するのはかなり新しいです。私はHttpModuleに対していくつかのユニットテストケースを作成していますが、次のようにstaticプロパティに到達するまですべて正常に動作します

this.applicationPath = (HttpRuntime.AppDomainAppVirtualPath.Length > 1) ? HttpRuntime.AppDomainAppVirtualPath : String.Empty;

staticクラスおよびHttpRuntime.AppDomainAppVirtualPathなどのプロパティのモックを作成する方法がわかりません。 contextrequest、およびresponseは、moqから取得したサンプルコードでうまくモックされています。誰かが私にこれを手伝ってくれれば幸いです。

41
jyothish george

Moqは静的メンバーを偽造することはできません。

ソリューションとして、静的プロパティを保持するラッパークラス(アダプターパターン)を作成し、そのメンバーを偽造できます。
例えば:

public class HttpRuntimeWrapper
{
    public virtual string AppDomainAppVirtualPath 
    { 
        get
        { 
            return HttpRuntime.AppDomainAppVirtualPath; 
        }
    }
}

本番コードでは、HttpRuntimeの代わりにこのクラスにアクセスして、このプロパティを偽造できます。

[Test]
public void AppDomainAppVirtualPathTest()
{
    var mock = new Moq.Mock<HttpRuntimeWrapper>();
    mock.Setup(fake => fake.AppDomainAppVirtualPath).Returns("FakedPath");

    Assert.AreEqual("FakedPath", mock.Object.AppDomainAppVirtualPath);
}

別の解決策は、静的なクラスとメンバーを偽造できる分離フレームワーク( Typemock Isolator )を使用することです。
例えば:

Isolate.WhenCalled(() => HttpRuntime.AppDomainAppVirtualPath)
       .WillReturn("FakedPath");

免責事項-私はTypemockで働いています

61
Elisha

Moqで静的メソッドをMoqすることはできません。

これは現実には悪いことではありません。静的メソッドとクラスには代わりがありますが、ロジックの場合は単体テストが難しくなります。当然、他のライブラリを使用するときにそれらに遭遇します。これを回避するには、静的コードの周りに adapter (wrapper)を記述し、インターフェースを提供する必要があります。例えば:

// Your static class - hard to mock
class StaticClass
{
   public static int ReturnOne() 
   {
       return 1;
   }
}

// Interface that you'll use for a wrapper
interface IStatic
{
    int ReturnOne();
}

注意してください、実動コードにIStaticを使用する具体的なクラスは省略しました。 IStaticを使用するクラスのみであり、実動コードは上記のStaticClassではなく、このクラスを使用します。

それからMoqで:

var staticMock = new Mock<IStatic>();
staticMock.Setup(s => s.ReturnOne()).Returns(2);
12
Finglas

前の回答で述べたように、静的メソッドでMoQを使用することはできません。必要な場合、最善の方法は静的クラスのラッパーを作成することです。

ただし、最近発見したのは Molesプロジェクト です。ホームページから。 「Molesでは、任意の.NETメソッドをデリゲートに置き換えることができます。Molesは、静的メソッドまたは非仮想メソッドをサポートしています。」あなたの現在の状況に役立つかもしれません。

3
Kirschstein

私がこれまでに見つけた最良の解決策は、Telerikの JustMock です-残念ながら、有料版のみが静的データのモックを許可します。

静的をラップするというアイデアは良いものですが、常にこれを行うことはできません。すでにいくつかの静的クラスを使用するコードをテストする場合、スイッチを切り替えてラッパーを使用できるとは限りません。この場合、JustMockは妥当なソリューションのように見えますが、近いうちにいくつかのソリューションで使用する予定です。

2
Ian

これにはMicrosoft Fakesを使用できます。それは間違いなく問題を解決します。 https://msdn.Microsoft.com/en-us/library/hh549175.aspxを参照してください

1
Sujith

@Sujithが示唆するように Microsoft Fakes を使用することは実行可能なソリューションです。実際に行う方法は次のとおりです。

  • テストプロジェクトの参照でSystem.Webを見つけ、右クリックします
  • 「追加」を選択します。これにより、参照System.Web.4.0.0.0.Fakesが追加されます
  • 次のコードを使用します。

    using(Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create()){System.Web.Fakes.ShimHttpRuntime.AppDomainAppVirtualPathGet =()=> "/"; //偽装AppDomainAppVirtualPathが必要なことを実行します}

0
Jack Miller