当测试具有主机类型“Moles”时,无法访问配置文件中的信息

时间:2012-02-02 17:47:51

标签: c# moles pex pex-and-moles

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

我们正在使用Visual Studio 2010,我相信我们已经在安装了VS 2010 SP1的计算机上安装了这个,并且没有安装SP1的计算机,以及在32位和64位计算机上尝试它。

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

首先,配置文件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"]);
            }

        }

    }

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

非常感谢,

尼克

3 个答案:

答案 0 :(得分:1)

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

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configurationFilePath;
System.Configuration.Configuration configuration =
    ConfigurationManager.OpenMappedExeConfiguration(
        fileMap,
        ConfigurationUserLevel.None);

答案 1 :(得分:1)

每次执行单元测试时,应通过依赖注入传递应用程序和用户设置。这是通过为设置创建一个Stub来实现的,这很容易做到。

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

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

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

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

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

  6. 当您不需要调整任何设置值时,请使用具体的TestSrtyingsStub。或者,当需要针对一个或两个测试调整值时,使用Miles Stub类型。 Moles Stub类型的目的是避免需要创建包含一个或两个唯一更改的许多存根。

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

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

    快乐的编码!

答案 2 :(得分:0)

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

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

语法是近似的 - 我不记得在这种情况下你是否最终得到了SConfigurationManager或MConfigurationManager。

我完全不同意迈克的观点是“......开发工作站无法访问外部依赖系统......”这句话很可怕。我们将这些东西称为集成测试。

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