包含XML作为单元测试的嵌入式资源?

时间:2011-10-06 07:03:20

标签: unit-testing

我有通过序列化XML文件初始化的对象。

我正在考虑将测试数据作为嵌入式资源包含在测试项目中,而不是在测试方法本身中“硬编码”数据。

嵌入式硬编码方法:

[Test]
public void IsMale_CheckIfGenderIsMale_ReturnsTrue()
{
Human human = new Human();
human.Gender = Gender.Male;
Gender expected = Gender.Male;
Assert.IsTrue((human.Gender == expected));
}

XML方法:

[Test]
public void IsMale_CheckIfGenderIsMale_ReturnsTrue()
{
Human human = Human.Initialize("Human_Male.xml");
Gender expected = Gender.Male;
Assert.IsTrue((human.Gender == expected));
}

哪种方法更好?

2 个答案:

答案 0 :(得分:0)

外部文件的唯一问题是它们可能会发生变化。

我首选的选项是在测试文件中有一系列初始化函数,可以在需要时从测试方法调用。这也使得可以更容易,更快速地阅读可能会在六个月内收集您的代码,甚至是您自己的其他人。

另一种选择是将一些对象类基于接口/抽象类型,以便您可以通过创建测试类来模拟它们(甚至在运行时代码中)。 例如(代码不可知):

  

基础抽象类/接口:IHuman IHuman.Gender   property / attribute IHuman.Height property / attribute IHuman.Weight   属性/属性

     

类HumanMale继承IHuman HumanMale.Gender会覆盖IHuman   性别归还男性。

     

类人类女性继承IHuman HumanFemale.Gender优先于IHuman   性别归还女性。

然后所有代码都使用IHuman,您甚至可以使用工厂创建IHuman类型来创建一大群网络人员:)

答案 1 :(得分:0)

我们经常在项目中使用嵌入式xml文件进行测试。因为我们想要使用xml测试对象的创建。

将对象的创建与类本身分开也是一种好习惯,例如:

Human human = HumanFactory.Create("Human_Male.xml");

然后人类会有一个构造函数,它接受像性别这样的参数,并且可以从HumanFactory类中调用。这是一种关注点的分离,它将使你的阶级逻辑与构建它的机制分开。

当您需要一个人类对象进行测试时,您可以选择直接创建它或使用工厂并从xml创建它。

我还会通过给它一个xml字符串(或Stream)而不是文件名来进一步简化HumanFactory类。这样可以更容易测试 - 因为您只需将xml包含在测试代码中而不是文件中:

Human human = HumanFactory.Create("<human gender="m"></human>");
Assert.AreEqual(human.Gender,  Gender.Male);

否则您的测试取决于:

  1. 将“Human_Male.xml”文件部署到文件系统的测试设置代码,然后将其删除。虽然Visual Studio测试有一个很好的机制来执行此操作(测试设置部署将文件作为测试运行设置的一部分复制到测试运行文件夹中)。
  2. 在测试代码中包含嵌入资源的路径。如果您应该重新构建项目布局,则需要更改测试代码以匹配。并确保使用相对路径。