麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

ASP.NET系列:?jiǎn)卧獪y(cè)試之ConfigurationManager

2019-11-14 14:27:24
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

通過(guò)ConfigurationManager使用.NET配置文件時(shí),可以通過(guò)添加配置文件進(jìn)行單元測(cè)試,雖然可以通過(guò)測(cè)試但達(dá)不到解耦的目的。使用IConfigurationManager和ConfigurationManagerWrapper對(duì)ConfigurationManager進(jìn)行適配是更好的方式,ConfigurationManagerWrapper提供.NET配置文件方式的實(shí)現(xiàn),如果需要支持其他配置,創(chuàng)建IConfigurationManager接口的不同的實(shí)現(xiàn)類即可。

1.定義IConfigurationManager接口

原本依賴ConfigurationManager的代碼現(xiàn)在依賴IConfigurationManager。可以在單元測(cè)試時(shí)方便的Mock。

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

2.創(chuàng)建適配類ConfigurationManagerWrapper

非單元測(cè)試環(huán)境使用ConfigurationManagerWrapper作為IConfigurationManager的默認(rèn)實(shí)現(xiàn)。

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.自定義泛型配置接口

在我們的代碼需要使用配置時(shí),可以考慮創(chuàng)建通用的泛型接口也可以使用專用的強(qiáng)類型的接口。這里演示使用通用的接口。

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

4.實(shí)現(xiàn)泛型接口配置接口的.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.對(duì)泛型配置接口的實(shí)現(xiàn)進(jìn)行單元測(cè)試

使用最流行的單元測(cè)試框架和Mock類庫(kù):xUnit+Moq進(jìn)行單元測(cè)試。

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 = 1;        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;    }}

運(yùn)行結(jié)果:

6.總結(jié)

使依賴ConfigurationManager靜態(tài)類的代碼轉(zhuǎn)換為依賴IConfigurationManager接口,運(yùn)行時(shí)注入ConfigurationManagerWrapper實(shí)現(xiàn)類。單元測(cè)試時(shí)使用Mock模擬IConfigurationManager對(duì)象。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美成人精品不卡视频在线观看 | 久久久久久久.comav | 成人做爽爽爽爽免费国产软件 | 午夜a狂野欧美一区二区 | 圆产精品久久久久久久久久久 | 超碰97人人艹 | 国产成人在线综合 | 国产精品久久久久久久亚洲按摩 | 国产在线播放91 | 亚洲日韩精品欧美一区二区 | 国产成人在线观看免费 | 看毛片的网址 | 国产亚洲综合一区二区 | 欧美日韩大片在线观看 | 国产精品自拍99 | 久久久久久久久淑女av国产精品 | 久草手机视频在线观看 | 国产亚洲区 | 日本a级免费 | 在线视频 欧美日韩 | 欧美成人小视频 | 韩国三级日本三级香港三级黄 | 精品国产一区在线 | fc2国产成人免费视频 | 免费欧美精品 | 超碰人人做人人爱 | 国产污污视频 | 国产91在线播放九色 | 成片免费观看视频大全 | 国产寡妇xxxxxxxx性开放 | 午夜色视频在线观看 | 九九热这里只有精品8 | 成人免费看片a | 久久久看 | 欧美老外a级毛片 | 日日草夜夜| 97视频 | 久久精品久久久久 | 国产日韩在线观看视频 | 国产伦精品一区二区三区 | 又黄又爽免费无遮挡在线观看 |