用NUnittestingapp.config文件

当你们unit testing一个依赖于app.config文件中的值的应用程序时? 如何testing这些值是否正确读取,以及程序如何对input到configuration文件中的错误值作出反应?

不得不修改NUnit应用程序的configuration文件是可笑的,但我不能读取我想testing的app.config中的值。

编辑:我想我应该澄清也许。 我并不担心ConfigurationManager无法读取这些值,但我担心testing程序如何响应读取的值。

我通常隔离外部依赖,比如在他们自己的外观类中读取一个configuration文件,而function很less。 在testing中,我可以创build这个类的模拟版本,实现和使用,而不是真正的configuration文件。 你可以创build自己的样机,或者使用像moq或rhino mock这样的框架。

这样,您可以轻松地使用不同的configuration值来尝试您的代码,而无需编写首先编写xmlconfiguration文件的复杂testing。 读取configuration的代码通常很简单,只需要很less的testing。

您可以在testing设置中的运行时修改您的configuration部分。 例如:

// setup System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.Sections.Add("sectionname", new ConfigSectionType()); ConfigSectionType section = (ConfigSectionType)config.GetSection("sectionname"); section.SomeProperty = "value_you_want_to_test_with"; config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("sectionname"); // carry out test ... 

你当然可以设置你自己的帮手方法,更优雅的做到这一点。

您可以调用ConfigurationManager.AppSettings的set方法来设置该特定unit testing所需的值。

 [SetUp] public void SetUp() { ConfigurationManager.AppSettings.Set("SettingKey" , "SettingValue"); // rest of unit test code follows } 

当unit testing运行时,它将使用这些值来运行代码

您可以使用ConfigurationManager类读取和写入app.config文件

我遇到了与web.config类似的问题….我find了一个有趣的解决scheme。 你可以封assembly置阅读function,例如:

 public class MyClass { public static Func<string, string> GetConfigValue = s => ConfigurationManager.AppSettings[s]; //... } 

然后正常使用

 string connectionString = MyClass.GetConfigValue("myConfigValue"); 

但在unit testing中初始化“覆盖”这样的function:

 MyClass.GetConfigValue = s => s == "myConfigValue" ? "Hi", "string.Empty"; 

更多关于它:

http://rogeralsing.com/2009/05/07/the-simplest-form-of-configurable-dependency-injection/

更优雅的解决scheme是在configuration设置本身上使用普通的旧dependency injection。 恕我直言,这是比不得不嘲笑configuration阅读类/包装等清洁。

例如,说一个类“天气”需要一个“ServiceUrl”才能正常工作(例如说它调用Web服务来获取天气)。 Weather代码可以允许一些代码积极地进入configuration文件来获取设置(不pipe代码是在Weather类中还是一个单独的configuration读取器,可以根据其他响应进行模拟),Weather类可以允许要注入的设置,可以通过parameter passing给构造函数,也可以通过属性设置器。 这样,unit testing非常简单直接,甚至不需要嘲笑。

然后可以使用Inversion of Control(或Dependency Injection)容器注入设置的值,因此Weather类的使用者不需要从某处显式提供值,因为它由容器处理。

这对我有用:

  public static void BasicSetup() { ConnectionStringSettings connectionStringSettings = new ConnectionStringSettings(); connectionStringSettings.Name = "testmasterconnection"; connectionStringSettings.ConnectionString = "server=localhost;user=some;database=some;port=3306;"; ConfigurationManager.ConnectionStrings.Clear(); ConfigurationManager.ConnectionStrings.Add(connectionStringSettings); } 

您始终可以将读入位包装在接口中,并从configuration文件中读取特定的实现。 然后,您将使用模拟对象编写testing,以查看程序如何处理错误的值。 就个人而言,我不会testing这个具体的实现,因为这是.NET框架代码(我假设 – 希望 – MS已经testing过)。

System.Configuration.Abstractions是关于testing这种东西的美丽的东西。

以下是GitHub项目网站的一些很好的例子: 在这里input链接描述

这里是NuGet站点: https : //www.nuget.org/packages/System.Configuration.Abstractions/

我几乎在所有的.NET项目中都使用这个。

其实,进一步思考,我想我应该做的是创build一个ConfigFileReader类在我的项目中使用,然后在unit testing线束中伪装它?

这是通常的事情吗?

最简单的select是包装读取configuration的方法,以便在testing期间replace值。 创build一个用于读取configuration的接口,并将该接口的实现作为构造函数parameter passing或作为属性设置在对象上(如使用dependency injection/控制反转)。 在生产环境中,传入一个真正从configuration中读取的实现; 在testing环境中,传入返回已知值的testing实现。

如果您没有重构可testing性代码的选项,但仍然需要对其进行testing,Typemock Isolator提供了实际模拟.NET框架configuration类的function,因此您可以只说“下一次我要求这样的 – 这样的appSettings值,返回这个已知的值。“

我遇到过同样的问题,

您可以使用Nunit-console.exe c:\ path1 \ testdll1.dll c:\ path2 \ testdll2.dll

这工作正常,即使如果两个DLL指向不同的app.configs前testdll1.dll.config和testdll2.dll.config

如果你想使用Nunit项目configuration和包装这两个DLL,那么你不可能有两个configuration

如果您的Nunit项目是project1.nunit与Project1.nunit位于同一位置,则必须具有project1.config。

希望这可以帮助

那么,我只是有同样的问题…我想testing一个网站引用的BL项目。 但我只想testingBL。 所以在testing项目的预生成事件中,我将app.Config文件复制到bin \ debug文件夹中,并从app.config中引用它们。