.NetCore技术研究-ConfigurationManager在单元测试下的坑
Posted lonelyxmas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.NetCore技术研究-ConfigurationManager在单元测试下的坑相关的知识,希望对你有一定的参考价值。
原文:.NetCore技术研究-ConfigurationManager在单元测试下的坑
最近在将原有代码迁移.NET Core, 代码的迁移基本很快,当然也遇到了不少坑,重构了不少,后续逐步总结分享给大家。今天总结分享一下ConfigurationManager遇到的一个问题。
先说一下场景:
迁移.NET Core后,已有的配置文件,我们希望做到兼容,比如说app.config和web.config,
这样配置文件尽可能地和.NET Framework是一套,尽可能低保持一致。比如:appSettings、自定义configSection等等。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <? xml version="1.0" encoding="utf-8" ?> < configuration > < configSections > << strong >section</ strong > name="CustomConfigs" type="ClassLibraryNetStandard.CustomConfigHandler, ClassLibraryNetStandard"/> </ configSections > << strong >CustomConfigs</ strong >> < CustomConfig name="service1" order="0" reflectconfig="ClassLibraryNetStandard.TestService, ClassLibraryNetStandard"/> < CustomConfig name="service2" order="1" reflectconfig="ClassLibraryNetStandard.TestService2, ClassLibraryNetStandard"/> </ CustomConfigs > << strong >appSettings</ strong >> < add key="service" value="service1"/> </ appSettings > </ configuration > |
对于上面配置读取我们做了以下几个事情
1. 添加Nuget:System.Configuration.ConfigurationManager
2. 保证原有自定义Section配置相关的代码、读取配置的代码,迁移到.NET Core后编译通过
3. 修改配置文件、单元测试
一、添加Nuget:System.Configuration.ConfigurationManager
搜索System.Configuration.ConfigurationManager:找到Nuget包,并添加引用:
二、保证原有自定义Section配置相关的代码、读取配置的代码,迁移到.NET Core后编译通过
示例代码中,自定义配置类CustomConfig:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using System; using System.Collections.Generic; using System.Text; namespace ClassLibraryNetStandard
public class CustomConfig
public string Name get ; set ; public string ReflectConfig get ; set ; public int Order get ; set ;
|
同时对应的Section配置节解析类:CustomConfigHandler,实现接口:System.Configuration.IConfigurationSectionHandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | using System; using System.Collections.Generic; using System.Text; using System.Xml; namespace ClassLibraryNetStandard
public class CustomConfigHandler : System.Configuration.IConfigurationSectionHandler
public object Create( object parent, object configContext, XmlNode section)
var configs = new List<CustomConfig>(); //获取配置文件中自定义节点值 foreach (XmlNode childNode in section.ChildNodes)
string name = null ; var config = new CustomConfig(); if (childNode.Attributes[ "name" ] != null )
name = childNode.Attributes[ "name" ].Value; config.Name = name; if (childNode.Attributes[ "order" ] != null )
config.Order = Convert.ToInt32(childNode.Attributes[ "order" ].Value);
if (childNode.Attributes[ "reflectconfig" ] != null )
config.ReflectConfig = childNode.Attributes[ "reflectconfig" ].Value; configs.Add(config);
return configs;
|
同时,我们编写了一个简单的配置管理类:CustomConfigManager,其中有配置读取方法,直接读取配置文件:
1 2 3 4 5 6 7 8 9 10 | public static List<CustomConfig> GetCustomConfigs()
var sectionConfig = System.Configuration.ConfigurationManager.GetSection( "CustomConfigs" ); if (sectionConfig != null )
return sectionConfig as List<CustomConfig>;
return null ;
|
这里我们使用了.NET Standard 2.0 library project,代码编译通过:
1>------ 已启动全部重新生成: 项目: ClassLibraryNetStandard, 配置: Debug Any CPU ------
1>C:\\Program Files\\dotnet\\sdk\\3.0.100-preview3-010431\\Sdks\\Microsoft.NET.Sdk\\targets\\Microsoft.NET.RuntimeIdentifierInference.targets(151,5): message NETSDK1057: 你正在使用 .NET Core 的预览版。请查看 https://aka.ms/dotnet-core-preview
1>ClassLibraryNetStandard -> C:\\Users\\***\\source\\repos\\NETFrameworkTest\\ClassLibraryNetStandard\\bin\\Debug\\netstandard2.0\\ClassLibraryNetStandard.dll
========== 全部重新生成: 成功 1 个,失败 0 个,跳过 0 个 ==========
三、修改配置文件、单元测试
添加MSTest单元测试工程:
增加App.config配置文件:
在单元测试方法中测试配置的读取:
1 2 3 4 5 6 | [TestMethod] public void ConfigTest()
var configs = ClassLibraryNetStandard.CustomConfigManager.GetCustomConfigs(); Assert.IsNotNull(configs);
|
原本以为,肯定可以获取到配置,实际获取的configs是null。
换了个Console类的应用,同样的配置文件读取,一点没有问题:
对比看了一下这两个工程,发现除了实际编译生成的配置文件名称不同,其他都一样。
问题肯定出在了单元测试工程上。Google了一下:有以下发现:
1 | MSTest is running as testhost.dll, which means that ConfigurationManager is reading settings from testhost.dll.config when executing under .NET core. < br >It will look for testhost.dll.config where the testhost.dll is located as the accepted answer states. < br >What is not mentioned is that it will also look for testhost.dll.config in the location where you have your test dlls. |
一句话:MSTest以testhost.dll运行,去取的配置文件是testhost.dll.config
这太尴尬了,直接无语,不过有两个解决方案:
1. 直接在单元测试工程中将app.config文件改为:testhost.dll.config
2. 修改单元测试工程文件,配置编译后事件,动态copy生成testhost.dll.config
试过之后,果真可以了,问题解决,分享给大家。
周国庆
2019/9/12
以上是关于.NetCore技术研究-ConfigurationManager在单元测试下的坑的主要内容,如果未能解决你的问题,请参考以下文章
.NetCore技术研究-一套代码同时支持.NET Framework和.NET Core
Consider defining a bean of type ‘com.example.springbootdemo.mapper.UserMapper‘ in your configuratio
Consider defining a bean of type ‘com.example.springbootdemo.mapper.UserMapper‘ in your configuratio