3

当单元测试的主机类型为“Moles”时,我们在通过单元测试访问 .net 配置文件(例如 app.config 和 web.config)中的信息时遇到问题。这引起了很多头痛,所以我希望有人知道可以做什么。

我们使用的是 Visual Studio 2010,我相信我们已经在安装了 VS 2010 SP1 的机器和未安装 SP1 的机器上进行了尝试,并在 32 位和 64 位机器上进行了尝试。

我冒昧地将测试简化为最简单的术语。可以通过编写由以下两个文件组成的单元测试项目并在取消注释唯一的注释行后运行测试来重新创建该问题。该测试在没有主机类型的情况下工作,但是当您将 Moles 作为主机类型引入时,测试中的 null 断言会失败。我们不确定为什么。

一、配置文件App.config:

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="Connection" connectionString="Something" />
  </connectionStrings>
</configuration>

接下来,包含单个测试的测试类:

namespace TestProject
    {
    using System.Configuration;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class UnitTest
        {

        [TestMethod]
        //[HostType("Moles")]
        public void TestMethod()
            {
            var data = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            Assert.IsNotNull(data.ConnectionStrings.ConnectionStrings["Connection"]);
            }

        }

    }

如果有人能提供任何见解,我将不胜感激。

非常感谢,

缺口

4

3 回答 3

1

我不确定它是否能完成这项工作,但您可以尝试这种解决方法:使用文件映射打开配置。代码将如下所示:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configurationFilePath;
System.Configuration.Configuration configuration =
    ConfigurationManager.OpenMappedExeConfiguration(
        fileMap,
        ConfigurationUserLevel.None);
于 2012-02-03T19:36:14.900 回答
1

任何时候执行单元测试,应用程序和用户设置都应该通过依赖注入传递。这是通过为设置创建一个存根来完成的,这很容易做到。

  1. 在正在测试的项目中创建一个接口,其中包含每个配置设置的属性。让我们称之为“ISettings”以供参考。

  2. 在实现接口的目标程序集中创建一个存根(类)。存根中的每个属性都应该只包含一个从配置文件返回相应设置的 get。我们将此存根称为“SettingsStub”。此存根由目标程序集在生产环境中使用。

  3. 将 ISettings 类型化参数添加到目标类型(正在测试的类)构造函数。目标类中的字段必须设置为传递给构造函数的 ISettings 对象。根据某些设计模式(MVVM 等)的要求,您可以创建重载构造函数并保留默认构造函数。默认构造函数(没有参数的构造函数)可以简单地实例化一个新的 SettingsStub,用于生产。测试必须始终使用重载的构造函数!

  4. 为测试项目创建一个设置存根,该存根也实现了 ISettings。我们将其称为 TestSettingsStub。此存根包含大多数测试可接受的硬编码值。

  5. 重建目标和测试项目。Moles 生成一个名为 SISettings 的 Stub 类型。

当您不需要调整任何设置值时,请使用具体的 TestSrtyingsStub。或者,当需要为一两个测试调整值时,使用 Miles Stub 类型。Moles Stub 类型的目的是避免制作包含一两个独特更改的许多存根。

在调用重载构造函数时,可以互换使用 SettingsStub、TestSettigsStub 和 SISettings 类型。现在,您可以完全控制在每个上下文中使用的设置,而无需在测试期间切换逻辑或手动更改设置值。目标代码只是从本地字段中检索设置值,而不是直接从配置文件中检索。请参阅依赖注入和控制反转 (IOC) 主题。

像往常一样,为了安全起见,您的开发工作站开发无法访问生产网络上的外部依赖系统(数据库等)!

快乐编码!

于 2012-02-04T19:30:50.057 回答
0

我同意迈克的回答在逻辑上是正确的(即您没有将配置加载与类分开 - 可能),实际问题是对于 Moles 主机类型,根据您的原始问题,您需要 Mole 调用到配置系统,例如

 MConfigurationManager.AllInstances.OpenExeConfiguration (... finish your moleing here...)

语法是近似的——我不记得在这种情况下你最终是 SConfigurationManager 还是 MConfigurationManager 。

我完全不同意 Mike 的地方在于,“......开发工作站无法访问外部依赖系统......”这句话是完全可怕的建议。我们将这些东西称为集成测试。

是的,您作为开发人员应该创建它们。在某些时候,您将编写涉及具体实现(例如数据库、支持服务等)的代码,如果您没有测试该交互,那么您几乎做错了。

于 2012-02-06T06:19:31.427 回答