在不使用Facade方法的情况下模拟ConfigurationManager.Appsetting

时间:2016-10-12 12:24:45

标签: c# unit-testing

我要测试一个方法,除了事实上我无法使用ConfigurationManager.AppSettings之外我完成了所有工作。

我的方法定义为

  public async Task<IDictionary<string, object>> Action(IDictionary<string, object> context)
    {
        if (ConfigurationManager.AppSettings[ApplicationUserFromDomainUserKey] == null)
            throw new ConfigurationErrorsException(ApplicationUserFromDomainUserKey);
        string storedProcedure = ConfigurationManager.AppSettings.Get(ApplicationUserFromDomainUserKey);

        if (ConfigurationManager.ConnectionStrings[DbConnectionKey] == null)
            throw new ConfigurationErrorsException(DbConnectionKey);
        ...

}

我在this question中看到过使用Facade方法的方法会很好但是它会破坏我的类实现,而不会使用IoC / DI

我也读过这个intresting article,但这仅适用于Vs企业版,我希望它可以在CI / VS专业版上运行

我正在使用NUnit进行测试,我的测试是

        [Test]
    public void MissingAppSettingsKey()
    {
            var pipeline = new RetrieveApplicationUsernamePipelineStep();

            var context = new Dictionary<string, object>()
            {
                [Resources.DomainUser] = "andrea",
                [Resources.Domain] = "ifinformatica.net",
                [Resources.ApplicationId] = 0
            };

            Assert.ThrowsAsync<ConfigurationErrorsException>(async () => await pipeline.Action(context));

        }

    }

P.S。我还使用resharper的工具进行测试,这也排除了我运行微软单元测试框架

1 个答案:

答案 0 :(得分:1)

更简单的方法是开始使用有限的DI实现来删除ConfigurationManager依赖。

重载您的构造函数(无论它是什么),将AppSettings条目作为参数。

所以如果你像这样创建了你的对象:

  MyObject myObj = new MyObject(SomeParam);

..使用构造函数声明...

  public MyObject(ParamObj someParam)
  {
    //...implementation....
  }

...像这样过载......

  public MyObject(ParamObj someParam)
   : this(someParam, Convert.ToInt32(ConfigurationManager.AppSettings["mySetting"]))
  {
    //...implementation....
  }


  public MyObject(ParamObj someParam, int mySettingValue)
  {
    //...implementation....
  }

这意味着在测试时,使用不调用/ require ConfigurationManager的构造函数构造对象。