如何设置IConfigurationRoot模拟返回值

时间:2017-04-25 18:48:40

标签: c# unit-testing asp.net-core moq xunit.net

我使用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:Expression引用一个方法   不属于模拟对象“

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:5)

  1. 将appSettings.json复制到Test项目根目录,并将其标记为内容,如果更新则将其标记为复制。

  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 []

  4. 一样访问它

答案 1 :(得分:1)

我认为你这样做的方法是构建可模拟的代理扩展方法,并使用它们。本地扩展方法可以覆盖外部方法,因此您可以创建自己的扩展类:

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/

另外,如果它有用,你也可以模拟字典的getter:

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