【问题标题】:Testing Methods with Reference to Web.Config in .Net C#.Net C# 中参考 Web.Config 的测试方法
【发布时间】:2012-05-15 01:15:15
【问题描述】:

我搜索了很多,但仍然找不到可靠的解决方案。假设您的应用程序中有方法。此方法使用“System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration”来访问 web.config 中的某些设置。如果您尝试测试这些方法,您的测试将失败,因为您的测试项目没有 web.config。

解决此问题的最佳方法是什么。对于配置文件简单的项目,我通常使用这样的方法作为外观方法。

public class Config
{
    public static String getKeyValue(String keyName)
    {
        if (keyName == String.Empty) return String.Empty;
        String result = "";

        System.Configuration.Configuration rootWebConfig1 =
           System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(null);
        if (rootWebConfig1.AppSettings.Settings.Count > 0)
        {
            System.Configuration.KeyValueConfigurationElement reportEngineKey =
                rootWebConfig1.AppSettings.Settings[keyName];

            if (reportEngineKey != null)
            {
                result = reportEngineKey.Value;

            }

        }

        return result;
    }
}

每次我尝试为 OpenWebConfiguration( ) 设置路径时,都会收到错误消息“不允许使用相对虚拟路径”

【问题讨论】:

    标签: asp.net asp.net-mvc-3 web-config


    【解决方案1】:

    为了使该场景更具可测试性,我通常采用自己制作“设置管理器”并为其提供接口的方法。比如:

    public interface IConfig
    {
        string GetSettingValue(string settingName);
    }
    

    然后我可以有我的“真正的”实现:

    public sealed class Config : IConfig
    {
        public string GetSettingValue(string settingName)
        {
            // your code from your getKeyValue() method would go here
        }
    }
    

    然后我使用它的代码将采用 this 的一个实例(这是 Dependency Inversion Principal 的一个示例):

    public void DoStuff(IConfig configuration)
    {
        string someSetting = configuration.GetSettingValue("ThatThingINeed");
        // use setting...
    }
    

    所以现在对于我的生产代码,我可以调用DoStuff 并传入Config 的实例。 当我需要测试时,我可以使用模拟工具(Moq、JustMock、RhinoMocks 等)来创建一个假的 IConfig,它会返回一个已知值而无需访问实际的 .config 文件,或者您可以在没有模拟框架的情况下执行此操作通过制作自己的模拟(并将它们存储在您的测试项目中)。

    public class ConfigMock : IConfig
    {
        private Dictionary<string, string> settings;
    
        public void SetSettingValue(string settingName, string value)
        {
            settings[settingName] = value;
        }
    
        public string GetSettingValue(string settingName)
        {
            return settings[settingName];
        }
    }
    

    [Test]
    public void SomeExampleTest()
    {
        var config = new ConfigMock();
        config.SetSettingValue("MySetting", "SomeValue");
    
        var underTest = new MyClass();
        underTest.DoStuff(config);
    }
    

    【讨论】:

    • 另请注意,这只是使其可测试的一种方法。这绝不是唯一的方法。还有一些可以模拟 static 方法的模拟框架,您可以使用其中之一来模拟您现有的 Config.getKeyValue() 方法,几乎​​没有其他代码更改。
    • 我要补充一点,kprobst 下面的答案与这个答案齐头并进。制作接口,然后使用 Moq 库(或其他模拟框架)构建 ConfigMock 在此答案中提供的模拟对象。
    • 谢谢!这似乎是一种干净且可重复使用的方法。
    【解决方案2】:

    最简单的方法是使用模拟库,例如moq。弄清楚它需要一些时间,但是一旦你这样做了,你就可以抽象出大部分管道,以返回可重复、一致的测试所需的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-24
      • 2020-12-12
      • 2011-03-12
      • 2013-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多