.NetCore技术研究-ConfigurationManager在单元测试下的坑

最近在将原有代码迁移.NET Core, 代码的迁移基本很快,当然也遇到了不少坑,重构了不少,后续逐步总结分享给大家。今天总结分享一下ConfigurationManager遇到的一个问题。

先说一下场景:

迁移.NET Core后,已有的配置文件,我们希望做到兼容,比如说app.config和web.config,

这样配置文件尽可能地和.NET Framework是一套,尽可能低保持一致。比如:appSettings自定义configSection等等。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="CustomConfigs" type="ClassLibraryNetStandard.CustomConfigHandler, ClassLibraryNetStandard"/>
  </configSections>
  <CustomConfigs>
    <CustomConfig name="service1" order="0" reflectconfig="ClassLibraryNetStandard.TestService, ClassLibraryNetStandard"/>
    <CustomConfig name="service2" order="1" reflectconfig="ClassLibraryNetStandard.TestService2, ClassLibraryNetStandard"/>
  </CustomConfigs>
  <appSettings>
    <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

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

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,其中有配置读取方法,直接读取配置文件:

        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配置文件:

在单元测试方法中测试配置的读取:

       [TestMethod]
        public void ConfigTest()
        {
            var configs = ClassLibraryNetStandard.CustomConfigManager.GetCustomConfigs();
            Assert.IsNotNull(configs);
        }

  原本以为,肯定可以获取到配置,实际获取的configs是null。

换了个Console类的应用,同样的配置文件读取,一点没有问题:

对比看了一下这两个工程,发现除了实际编译生成的配置文件名称不同,其他都一样。

问题肯定出在了单元测试工程上。Google了一下:有以下发现:

MSTest is running as testhost.dll, which means that ConfigurationManager is reading settings from testhost.dll.config when executing under .NET core. It will look for testhost.dll.config where the testhost.dll is located as the accepted answer states. 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

原文地址:https://www.cnblogs.com/tianqing/p/11514840.html

时间: 2024-11-06 07:09:28

.NetCore技术研究-ConfigurationManager在单元测试下的坑的相关文章

.NetCore技术研究-一套代码同时支持.NET Framework和.NET Core

在.NET Core的迁移过程中,我们将原有的.NET Framework代码迁移到.NET Core.如果线上只有一个小型的应用还好,迁移升级完成后,只需要维护.NET Core这个版本的代码. 但是,如果是一个大型分布式应用,几百台Server,上千个.NET 应用进程.这种场景下,在一定的时期内,我们需要同时维护.NET Framework和.NET Core两套代码,同一个产品 特性,需要分别在两套代码中实现,这种代码同步的工作量是非常大的.因此,在这种场景下,有必要使用同一套代码既支持

.NetCore技术研究-.NET Core迁移前的准备工作

前段时间迁移.NET Core做了大量的试水和评估,今天整理一下分享给大家.大致有以下几个部分: 1. .NET Core的由来 2. 为什么要迁移.NET Core 3. .NET Core3.X主要特性 4. .NET Standard和.NET Core 5. .NET Core Roadmap&版本选择 接下来,我们详细展开说吧. 一..NET Core的由来 这个更像是科普的资料,因为团队的小伙伴有半路出家的,对.NET 的光辉历史不是非常了解,所以有必要带着大家看一遍.NETCore

.NET Core技术研究-最实用最常用的配置读取方式

原文:.NET Core技术研究-最实用最常用的配置读取方式 升级ASP.NET Core后,配置的读取是第一个要明确的技术.原先的App.Config.Web.Config.自定义Config在ASP.NET Core中如何正常使用.有必要好好总结整理一下,相信大家都会用到. 首先,看一下ASP.NET Core中的配置提供程序(Configuration Providers): 一.配置提供程序(Configuration Providers) ASP.NET Core 使用一个或多个配置提

虚拟化技术研究及架构分析

什么是虚拟化 虚拟化是指计算机元件在虚拟的基础上而不是真实的基础上运行.虚拟化技术可以扩大硬件的容量,简化软件的重新配置过程.CPU的虚拟化技术可以单CPU模拟多CPU并行,允许一个平台同时运行多个操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率. 几种虚拟化软件介绍 RedHat KVM 虚拟化方式:完全虚拟化 架构:寄居架构(linux内核);祼金属架构RHEV-H 特点:祼金属架构RHEV-H或在关键的硬盘和网卡上支持半虚拟化VirtIO,达到最佳

小雷郑重承诺:在2017年之前,对大学毕业4年以来的所有努力和探索,做一个全面客观的总结,技术研究、工作创业、投资理财、朋友感情等

又是新的一年,祝各位上班族,开工大吉.祝各位朋友,身体健康,开开心心赚钱过日子. 回家过了12天,经历了一些事情,放佛过了好久好久,有几年的样子. 回首过去,惨惨的,真的很惨.一点拿得出手的成绩和成就都没有,太让自己失望了. 过去的2014和2015,混的确实太惨,我都不好意思去写总结.很多计划没实现,夭折的故事也太多了.总之,过去不敢去回顾. 2016年又正式开始了,有些感慨.现在还不方便,对过去"盖棺定论" .希望,在2017年之前,能有一个认真的回顾和总结. 坦诚地面对过去的探索

JS魔法堂:元素克隆、剪切技术研究

原文:JS魔法堂:元素克隆.剪切技术研究 一.前言 当需要新元素时我们可以通过 document.createElement 接口来创建一个全新的元素,也可以通过克隆已有元素的方式来获取一个新元素.而在部分浏览器中,通过复制来获取新元素的效率比通过 document.createElement 方式的要高一些,具体的性能比较如下: 2% in IE8, but no change in IE6 and IE7 Up to 5.5% in Firefox 3.5 and Safari 4 6% i

Azure IoT 技术研究系列2-设备注册到Azure IoT Hub

上篇博文中,我们主要介绍了Azure IoT Hub的基本概念.架构.特性: Azure IoT 技术研究系列1-入门篇 本文中,我们继续深入研究,做一个起步示例程序:模拟设备注册到Azure IoT Hub, 设备到云通信,云到设备通信. 整体篇幅较大,我们先来第一步:将模拟设备注册到Azure IoT Hub. 首先,我们需要有一个联网的设备,例如树莓派.Win10 IoT设备等等,只要能联网,Azure IoT Hub有编程SDK即可,为了方便演示,本篇中我们做了一个模拟设备: TeldP

伪AP检测技术研究

转载自:http://www.whitecell-club.org/?p=310 随着城市无线局域网热点在公共场所大规模的部署,无线局域网安全变得尤为突出和重要,其中伪AP钓鱼攻击是无线网络中严重的安全威胁之一. 受到各种客观因素的限制,很多数据在WiFi网络上传输时都是明文的,如一般的网页.图片等:甚至还有很多网站或邮件系统在手机用户进行登陆时,将帐号和密码也进行了明文传输或只是简单加密传输(加密过程可逆).因此,一旦有手机接入攻击者架设的伪AP,那么通过该伪AP传输的各种信息,包括帐号和密码

重复数据删除(De-duplication)技术研究(SourceForge上发布dedup util)

dedup util是一款开源的轻量级文件打包工具,它基于块级的重复数据删除技术,可以有效缩减数据容量,节省用户存储空间.目前已经在Sourceforge上创建项目,并且源码正在不断更新中.该工具生成的数据包内部数据部局(layout)如下: --------------------------------------------------| header | unique block data | file metadata |--------------------------------