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 ...
随机推荐
- 神奇的decimal,也许面试会问到哦~
这段时间忙的像狗一样,写博客的事情也就耽搁了,继续扯,为什么说decimal神奇呢,大家都知道decimal是基元类型,但是 这个decimal类型在IL中居然没有相应的IL指令,也就是说CLR根本不 ...
- Java堆、栈和常量池
摘录自 http://www.cnblogs.com/xiohao/p/4296088.html 1. 栈(stack)与堆(heap)都是Java用来在RAM中存放数据的地方.与C++不同,Java ...
- 一篇博客理解Recyclerview的使用
从Android 5.0开始,谷歌公司推出了RecylerView控件,当看到RecylerView这个新控件的时候,大部分人会首先发出一个疑问,recylerview是什么?为什么会有recyler ...
- linux创建用户、设置密码、修改用户、删除用户
创建用户.设置密码.修改用户.删除用户:useradd testuser 创建用户testuserpasswd testuser 给已创建的用户testuser设置密码说明:新创建的用户会在/home ...
- 使用自定义setTimeout和setInterval使之可以传递参数和对象参数
转载自http://www.jb51.net/article/17859.htm /****************************************************** // ...
- js实现打开网页自动弹出添加QQ好友邀请窗口
我们有时进一些网面或专题页面会自动弹出一个加为好友的对话框了,在研究了很久之后发现可以直接使用js来实现,下面我们一起来看js实现打开网页自动弹出添加QQ好友邀请窗口的方法. 第一步.JS脚本 这个是 ...
- [转]C#网络编程(订立协议和发送文件) - Part.4
本文转自:http://www.tracefact.net/CSharp-Programming/Network-Programming-Part4.aspx 源码下载:http://www.trac ...
- java使用IO读写文件总结
每次用到IO的读写文件都老忘记写法,都要翻过往笔记,今天总结下,省的以后老忘.java读写文件的IO流分两大类,字节流和字符流,基类分别是字符:Reader和Writer:字节:InputStream ...
- 扫盲 BT Sync——不仅是同步利器,而且是【分布式】网盘
先向大伙儿宣布个好消息-- 经过多位热心读者的大力支持,经过几天的努力,已经完成了"微软网盘"到"BitTorrent Sync"的迁移工作. 再次向这批热心读 ...
- 模版(template)
模版(template) 在c++Template中很多地方都用到了typename与class这两个关键字,而且好像可以替换,是不是这两个关键字完全一样呢? 相信学习C++的人对class这个关键字 ...