9

MVC3 Web プロジェクトでコントローラーの単体テストを作成していますが、次のようなリソースにアクセスしようとすると、テストで例外がスローされます。

return Index(Resources.Strings.MyStringResource);

リソースは、.resxというタイトルのファイルですStrings

私はMoqライブラリを使用してHttpContextBase機能の単体テストを実行しているので、Moq ライブラリを使用して App_GlobalResource にアクセスするにはどうすればよいか疑問に思っていました。

どんな助けや指針も大歓迎です!

4

3 に答える 3

5

少なくとも直接的にはできません。リソース (.resx) ファイルから生成される厳密に型指定されたクラスは、インスタンス メソッドではなく静的を公開します。

このため、インターフェイス メソッドを実装することも、仮想化することもできません。Moqでは、モックを作成するために、これらの条件の少なくとも 1 つが満たされている必要があります。

これを回避するには、他のものと同様に抽象化を作成します。

public interface IResources
{
    string MyStringResource { get; }
}

これの実装をコントローラーに渡し (または挿入し)、それをIndexメソッドに渡します。その実装は次のようになります。

public class ResourcesWrapper : IResources
{
    public string MyStringResource 
    { 
        get 
        { 
            return Resources.Strings.MyStringResource; 
        } 
    }
}

次に、テストするときに、Moq を使用してIResourcesインターフェースのモックを作成し、それをコントローラーに渡すことができます。

// Create the mock.
var mock = new Mock<IResources>();

// Setup the property.
mock.SetupProperty(m => m.MyStringResource, "My Mocked Value");

// Pass the object somewhere for use.
Assert.AreEqual(mock.Object.MyStringResource, "My Mocked Value");
于 2012-10-22T17:32:04.397 に答える
2

したがって、casperOneの回答を実装した後、別のエラーが発生しました。

私は次のようにIOException述べられました:

"Could not load file or assembly 'App_GlobalResources' or one of its dependencies. The system cannot find the file specified.":"App_GlobalResources"

スコット・アレンは、この問題の理由と固有の解決策を提供しました。

それで、私がしたことは、私のWebプロジェクトの「TResources」という名前の新しいフォルダーに「TResources」という名前の新しいリソースファイルを作成したことです。これは、テスト目的でのみ作成および使用されるResourcesフォルダーだからです(賢いですね)。

ResourcesWrapper次に、クラスのプロパティを変更して、TResources.Strings.MyStringResourceではなくreturnに変更しましたResources.Strings.MyStringResource

注:モックオブジェクトを設定する場合のように、インターフェイスのプロパティは読み取り専用IResourcesあってはなりません。プロパティが読み取り専用の場合、値を設定できないため失敗します。

したがって、IResources次のようになります。

public interface IResources
{
    string MyStringResource { get; set; }
}

ResourcesWrapperIResources次に、次のように実装する必要があります。

public class ResourcesWrapper : IResources
{
    public string MyStringResource 
    { 
        get 
        { 
            return TResources.Strings.MyStringResource; 
        } 
        set
        {
            //do nothing
        }
    }
}

これにより、次のように、単体テストでモックを成功させることができます。

var mock = new Mock<IResources>();
mock.SetupProperty(m => m.MyStringResource, "");

注:initialValueプロパティはから取得した値を返すため、上記のメソッドのパラメーターに何も指定する必要はありませんStrings.resx

これで私の質問は終わりです。これがインターネット上の他の誰かに役立つことを願っています。

于 2012-10-23T20:20:42.293 に答える