web-dev-qa-db-ja.com

IConfigurationRootのモックを設定して値を返す方法

IConfigurationRouteを使用して、このようなディレクトリにアクセスしました。

if (type == "error") directory = _config.GetValue<string>("Directories:SomeDirectory");

_configは、コンストラクターに注入されるIConfigurationRootです。

私はそれをモックするために次の方法を試しました。

        var mockConfigurationRoot = new Mock<IConfigurationRoot>();
        mockConfigurationRoot.Setup(c => c.GetValue<string>("Directories: SomeDirectory"))
            .Returns("SomeDirectory")
            .Verifiable();
        var config = mockConfigurationRoot.Object;

問題は、テストの実行中にXunitが例外をスローすることです

「System.NotSupportedException:式は、モックされたオブジェクトに属さないメソッドを参照しています」

この問題を解決するにはどうすればよいですか?

13
Virodh

SetupGetメソッドを次のように使用して実行しました。それは私のために働く、それが役立つことを願っています。

_configurationRoot = new Mock<IConfigurationRoot>();
_configurationRoot.SetupGet(x => x[It.IsAny<string>()]).Returns("the string you want to return");
21
user3130628
  1. AppSettings.jsonをテストプロジェクトのルートディレクトリにコピーし、そのプロパティをコンテンツとしてマークし、新しい場合はコピーします。

  2. var builder = new ConfigurationBuilder()
          .SetBasePath(Directory.GetCurrentDirectory())
          .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
          .AddEnvironmentVariables();
    ConfigurationManager.Configuration = builder.Build();
    
  3. ConfigurationManagerはクラスであり、静的プロパティConfigurationがあります。これにより、アプリケーション全体がConfigurationManager.Configuration []としてアクセスできます。

あなたがそれを行う方法は、モック可能なプロキシ拡張メソッドを構築し、代わりにそれらを使用することだと思います。ローカル拡張メソッドは外部メソッドをオーバーライドできるため、独自の拡張クラスを作成できます。

public static class ConfigurationExtensions
{
    public static IConfigurationProxy Proxy = new ConfigurationProxy();
    public static T GetValue<T>(this IConfigurationRoot config, string key) => Proxy.GetValue<T>(config, key);
}

次に、プロキシをセットアップします。

public class ConfigurationProxy : IConfigurationProxy
{
    public T GetValue<T>(IConfigurationRoot config, string key) => config.GetValue<T>(key);
}

次に、モック可能な拡張メソッドを使用する各クラスで、静的コンストラクターを追加します。

static MyClass()
{
    ConfigurationExtensions.Proxy = new ConfigurationProxy();
}

または

static MyClass_Tests()
{
    ConfigurationExtensions.Proxy = Mock.Of<IConfigurationProxy>();
}

使用する必要のある拡張方法ごとに、洗浄、すすぎ、繰り返します。詳細については、こちらをご覧ください: http://blogs.clariusconsulting.net/kzu/how-to-design-a-unit-testable-domain-model-with-entity-framework-code-first/

また、役立つ場合は、辞書のゲッターをモックすることもできます。

mockConfigurationRoot.SetupGet(m => m["ConnectionStrings:Repository"]).Returns("bogus");
1
Chris D