ASP.NET 系列:单元测试之ConfigurationManager
通过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的更多相关文章
- 补习系列(8)-springboot 单元测试之道
目录 目标 一.About 单元测试 二.About Junit 三.SpringBoot-单元测试 项目依赖 测试样例 四.Mock测试 五.最后 目标 了解 单元测试的背景 了解如何 利用 spr ...
- 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单元测试 ...
- 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 ...
- ASP.NET 系列:单元测试
单元测试可以有效的可以在编码.设计.调试到重构等多方面显著提升我们的工作效率和质量.github上可供参考和学习的各种开源项目众多,NopCommerce.Orchard等以及微软的asp.net m ...
- [转载]单元测试之道(使用NUnit)
首先来看下面几个场景你是否熟悉 1.你正在开发一个系统,你不断地编码-编译-调试-编码-编译-调试……终于,你负责的功能模块从上到下全部完成且编译通过!你长出一口气,怀着激动而又忐忑的心情点击界面上的 ...
- 单元测试之道(使用NUnit)
首先来看下面几个场景你是否熟悉 1.你正在开发一个系统,你不断地编码-编译-调试-编码-编译-调试……终于,你负责的功能模块从上到下全部完成且编译通过!你长出一口气,怀着激动而 又忐忑的心情点击界面上 ...
- 使用VisualStudio进行单元测试之二
借着工作忙的借口,偷了两天懒,今天继续单元测试之旅.前面说了如何进行一个最简单的单元测试,这次呢就跟大家一起来熟悉一下,在visual studio中如何进行数据驱动的单元测试. 开始之前先来明确一下 ...
- iOS 单元测试之XCTest详解(一)
iOS 单元测试之XCTest详解(一) http://blog.csdn.net/hello_hwc/article/details/46671053 原创blog,转载请注明出处 blog.csd ...
- 玩转单元测试之Testing Spring MVC Controllers
玩转单元测试之 Testing Spring MVC Controllers 转载注明出处:http://www.cnblogs.com/wade-xu/p/4311657.html The Spri ...
随机推荐
- 记录一些在用wcf的过程中走过的泥巴路 【第一篇】
自从转移战场之后,比以前忙多了,博客也没能及时跟上,原本准备继续mvc系列,但是在那边技术比较陈旧还没能用得上,话说有3年没接触这玩意了,东西也 都忘了差不多了,既然再次接触,我也就继续温习温习,记录 ...
- lnmp之php5.3.27 编译信息
./configure \--prefix=/application/php5.3.27 --with-mysql=application/mysql \--with-iconv-dir=/usr/l ...
- Java并发之CyclicBarrier 可重用同步工具类
package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * Cyclic ...
- W3School-CSS 字体(font)实例
CSS 字体(font)实例 CSS 实例 CSS 背景实例 CSS 文本实例 CSS 字体(font)实例 CSS 边框(border)实例 CSS 外边距 (margin) 实例 CSS 内边距 ...
- Mysql常用的一些技巧命令
1.统计指定数据库下表的数量 mysql > use information_schema; mysql > SELECT count(TABLE_NAME) FROM informati ...
- iOS Build Active Architecture Only 属性的理解(及 not found for architecture i386 的解决方案)
最近做项目过程遇到一个问题: 涉及到这个属性:Build Active Architecture Only Yes .No的区别: 设置为yes,是只编译当前的architecture版本,是为了编译 ...
- Android getevent
详细用法如下: 源码复制打印? Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] ...
- Android 的提权 (Root) 原理是什么?
作者:Kevin链接:https://www.zhihu.com/question/21074979/answer/18176410来源:知乎著作权归作者所有,转载请联系作者获得授权. Android ...
- HashMap和HashSet
Java使用Set接口来描述集合,而Set中每一个数据元素都是唯一的. HashSet散列集合 Hash算法:把任意长度输入,通过散列算法,变换成固定长度的输出即散列值.对不同类型信息,散列值公式也是 ...
- 理解 OpenStack + Ceph (4):Ceph 的基础数据结构 [Pool, Image, Snapshot, Clone]
本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...