开发者

Include XML as an embedded resource for unit testing?

开发者 https://www.devze.com 2023-04-11 16:31 出处:网络
I have objects that gets initialized by serializing an XML file. I\'m thinking of including the test data in the test project as an embedded resource instead of \"hard-coding\" the data in the test m

I have objects that gets initialized by serializing an XML file.

I'm thinking of including the test data in the test project as an embedded resource instead of "hard-coding" the data in the test method itself.

Embedded Hard-coded approach:

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

XML approach:

[Test]
public void IsMale_CheckIfGenderIsMale_ReturnsTrue()
{
Human human = Human.Initialize("Human_Male.xml");
Gender expecte开发者_如何学Pythond = Gender.Male;
Assert.IsTrue((human.Gender == expected));
}

Which is a better approach?


We often use embedded xml files in our project for testing. Because we want to test the creation of objects using xml.

It is also good practice to separate the creation of objects from the class itself, for example:

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

The human class would then have a constructor which takes parameters like gender, and can be called from the HumanFactory class. It's a separation of concerns that will keep the logic of your class separate from the mechanism of building it.

And when you need a human object for a test, you can choose either to create it directly or use the factory and create it from xml.

I would also simplify the HumanFactory class further, by giving it an xml string (or Stream) instead of a filename. This can make it easier to test - because you can just include the xml in your test code and not in a file:

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

Otherwise your test depends on either:

  1. the test setup code deploying the "Human_Male.xml" file to the file system, and removing it afterwards. Although Visual Studio test has a nice mechanism to do this (test settings deployment will copy files into the test run folder as part of the test run setup).
  2. Including a path to the embedded resource in your test code. If you should ever restructure your project layout, you will need to change the test code to match. And make sure you use a relative path.


The only problem with external files is that they may change.

My preferred option is to have a series of initialisation functions within the test file that can be called from the test method as and when required. This also makes for easier and quicker reading for others that may pick up your code, or even yourself in six months time.

Another option is to base some of your object classes around an interface/abstract type so that you can mock them (even in your runtime code) by creating a test class instead. For example (code agnostic):

base abstract class/interface: IHuman IHuman.Gender property/attribute IHuman.Height property/attribute IHuman.Weight property/attribute

class HumanMale inherits IHuman HumanMale.Gender overrides IHuman Gender to return Male.

class HumanFemale inherits IHuman HumanFemale.Gender overrides IHuman Gender to return Female.

All code then uses IHuman and you can even use a factory to create IHuman types to create a legion of cybermen :)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号