通过ConfigurationManager使用.NET配置文件时,可以通过添加配置文件进行单元测试,虽然可以通过测试但达不到解耦的目的。使用IConfigurationManager和ConfigurationManagerWrapper对ConfigurationManager进行适配是更好的方式,ConfigurationManagerWrapper提供.NET配置文件方式的实现,如果需要支持其他配置,创建IConfigurationManager接口的不同的实现类即可。

1.定义IConfigurationManager接口

原本依赖ConfigurationManager的代码现在依赖IConfigurationManager。可以在单元测试时方便的Mock。

public interface IConfigurationManager
{
NameValueCollection AppSettings { get; }
ConnectionStringSettingsCollection ConnectionStrings { get; }
object GetSection(string sectionName);
}

2.创建适配类ConfigurationManagerWrapper

非单元测试环境使用ConfigurationManagerWrapper作为IConfigurationManager的默认实现。

public class ConfigurationManagerWrapper : IConfigurationManager
{
public NameValueCollection AppSettings
{
get
{
return ConfigurationManager.AppSettings;
}
} public ConnectionStringSettingsCollection ConnectionStrings
{
get
{
return ConfigurationManager.ConnectionStrings;
}
} public object GetSection(string sectionName)
{
return ConfigurationManager.GetSection(sectionName);
}
}

3.自定义泛型配置接口

在我们的代码需要使用配置时,可以考虑创建通用的泛型接口也可以使用专用的强类型的接口。这里演示使用通用的接口。

public interface IConfiguration
{
T Get<T>(string key, T @default);
}

4.实现泛型接口配置接口的.NET配置文件版本

AppConfigAdapter直接不使用ConfigurationManager而是依赖IConfigurationManager接口。

public class AppConfigAdapter : IConfiguration
{
private IConfigurationManager _configurationManager; public AppConfigAdapter(IConfigurationManager configurationManager)
{
this._configurationManager = configurationManager;
} public T Get<T>(string nodeName, T @default)
{
var value = this._configurationManager.AppSettings[nodeName];
return value == null ? @default : (T)Convert.ChangeType(value, typeof(T));
}
}

5.对泛型配置接口的实现进行单元测试

使用最流行的单元测试框架和Mock类库:xUnit+Moq进行单元测试。

public class AppConfigAdapterTest
{
[Fact]
public void GetStringTest()
{
var key = "key";
var value = "value";
var configuration = new AppConfigAdapter(this.GetConfigurationManager(o => o.Add(key, value.ToString())));
Assert.Equal(configuration.Get(key, string.Empty), value);
} [Fact]
public void GetIntTest()
{
var key = "key";
var value = ;
var configuration = new AppConfigAdapter(this.GetConfigurationManager(o => o.Add(key, value.ToString())));
Assert.Equal(configuration.Get(key, int.MinValue), value);
} [Fact]
public void GetBoolTest()
{
var key = "key";
var value = true;
var configuration = new AppConfigAdapter(this.GetConfigurationManager(o => o.Add(key, value.ToString())));
Assert.Equal(configuration.Get(key, false), value);
} [Fact]
public void GetDateTimeTest()
{
var key = "key";
var value = DateTime.Parse(DateTime.Now.ToString());
var configuration = new AppConfigAdapter(this.GetConfigurationManager(o => o.Add(key, value.ToString())));
Assert.Equal(configuration.Get(key, DateTime.MinValue), value);
} [Fact]
public void GetDecimalTest()
{
var key = "key";
var value = 1.1m;
var configuration = new AppConfigAdapter(this.GetConfigurationManager(o => o.Add(key, value.ToString())));
Assert.Equal(configuration.Get(key, decimal.MinValue), value);
} private IConfigurationManager GetConfigurationManager(Action<NameValueCollection> set)
{
var appSettings = new NameValueCollection();
set(appSettings);
var configurationManager = new Mock<IConfigurationManager>();
configurationManager.Setup(o => o.AppSettings).Returns(appSettings);
return configurationManager.Object;
}
}

运行结果:

6.总结

使依赖ConfigurationManager静态类的代码转换为依赖IConfigurationManager接口,运行时注入ConfigurationManagerWrapper实现类。单元测试时使用Mock模拟IConfigurationManager对象。

ASP.NET 系列:单元测试之ConfigurationManager的更多相关文章

  1. 补习系列(8)-springboot 单元测试之道

    目录 目标 一.About 单元测试 二.About Junit 三.SpringBoot-单元测试 项目依赖 测试样例 四.Mock测试 五.最后 目标 了解 单元测试的背景 了解如何 利用 spr ...

  2. ASP.NET Core搭建多层网站架构【3-xUnit单元测试之简单方法测试】

    2020/01/28, ASP.NET Core 3.1, VS2019, xUnit 2.4.0 摘要:基于ASP.NET Core 3.1 WebApi搭建后端多层网站架构[3-xUnit单元测试 ...

  3. ASP.NET Core搭建多层网站架构【12-xUnit单元测试之集成测试】

    2020/02/01, ASP.NET Core 3.1, VS2019, xunit 2.4.1, Microsoft.AspNetCore.TestHost 3.1.1 摘要:基于ASP.NET ...

  4. ASP.NET 系列:单元测试

    单元测试可以有效的可以在编码.设计.调试到重构等多方面显著提升我们的工作效率和质量.github上可供参考和学习的各种开源项目众多,NopCommerce.Orchard等以及微软的asp.net m ...

  5. [转载]单元测试之道(使用NUnit)

    首先来看下面几个场景你是否熟悉 1.你正在开发一个系统,你不断地编码-编译-调试-编码-编译-调试……终于,你负责的功能模块从上到下全部完成且编译通过!你长出一口气,怀着激动而又忐忑的心情点击界面上的 ...

  6. 单元测试之道(使用NUnit)

    首先来看下面几个场景你是否熟悉 1.你正在开发一个系统,你不断地编码-编译-调试-编码-编译-调试……终于,你负责的功能模块从上到下全部完成且编译通过!你长出一口气,怀着激动而 又忐忑的心情点击界面上 ...

  7. 使用VisualStudio进行单元测试之二

    借着工作忙的借口,偷了两天懒,今天继续单元测试之旅.前面说了如何进行一个最简单的单元测试,这次呢就跟大家一起来熟悉一下,在visual studio中如何进行数据驱动的单元测试. 开始之前先来明确一下 ...

  8. iOS 单元测试之XCTest详解(一)

    iOS 单元测试之XCTest详解(一) http://blog.csdn.net/hello_hwc/article/details/46671053 原创blog,转载请注明出处 blog.csd ...

  9. 玩转单元测试之Testing Spring MVC Controllers

    玩转单元测试之 Testing Spring MVC Controllers 转载注明出处:http://www.cnblogs.com/wade-xu/p/4311657.html The Spri ...

随机推荐

  1. Sql Server之旅——第三站 解惑那些背了多年聚集索引的人

    说到聚集索引,我想每个码农都明白,但是也有很多像我这样的猥程序员,只能用死记硬背来解决这个问题,什么表中只能建一个聚集索引, 然后又扯到了目录查找来帮助读者记忆....问题就在这里,我们不是学文科,, ...

  2. Javascript之旅——第十一站:原型也不好理解?

    写到这篇,我的js系列也快接近尾声了,所以这个系列不会遗留js来实现面向对象的核心——原型,有些人说原型不好理解,其实嘛,要想系统 的理解原型,最便捷的方式就是看看经典的书,少看些博客,博客这东西只是 ...

  3. mysql datetime查询异常

    mysql datetime查询异常 异常:Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp (2011 ...

  4. 004.UDP--拼接UDP数据包,构造ip头和udp头通信(使用原始套接字)

    一.大致流程: 建立一个client端,一个server端,自己构建IP头和UDP头,写入数据(hello,world!)后通过原始套接字(SOCK_RAW)将包发出去. server端收到数据后,打 ...

  5. 使用HTTP方式远程连接PowerShell

    借助Windows PowerShell,我们可以像管理Linux一样使用命令行来远程管理Windows服务器.但是默认情况下,我们只能在域环境中使用PowerShell Remoting.如果是通过 ...

  6. [转]ASP.NET 成员资格 Part.1(API)

    本文转自:http://www.cnblogs.com/SkySoot/archive/2013/04/08/3008418.html 表单验证解决了 ASP.NET 应用程序页面验证的问题,但另一方 ...

  7. 洛谷⑨月月赛Round2 P3392涂国旗[DP]

    题目描述 某国法律规定,只要一个由N*M个小方块组成的旗帜符合如下规则,就是合法的国旗.(毛熊:阿嚏——) 从最上方若干行(>=1)的格子全部是白色的. 接下来若干行(>=1)的格子全部是 ...

  8. java分层开发

    既然是分层开发,首先我们需要知道的是分为那几个层,并且是干什么的? 1.实体层(entity) 对应数据库中的一张表,有了它可以降低耦合性,同时也是数据的载体. 2.数据访问对象(data acces ...

  9. AC日记——鬼谷子的钱袋 codevs 2998

    2998 鬼谷子的钱袋 2006年省队选拔赛湖南  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master    题目描述 Description 鬼谷子非常聪明,正 ...

  10. Java深入 - Java 内存分配和回收机制

    Java的GC机制是自动进行的,和c语言有些区别需要程序员自己保证内存的使用和回收. Java的内存分配和回收也主要在Java的堆上进行的,Java的堆中存储了大量的对象实例,所以Java的堆也叫GC ...