Daily Archives: 11 August 2013

DeploymentItem Attribute and UnitTesting With Visual Studio

I set out to do some unit testing today and forgot an important step which is required to use the DeploymentItem attribute. To set the scene, the method I was testing retrieved a FileStream in its internals. That is, the FileStream was not the returned object; it was something which the method required to do its thing. And I wasn’ going to unit test the .NET Framework method that gets the FileStream as that would be quite pointless.
The reason the Deployment Item attribute here was a great option was because it auto-magically took care of the the File IO and let me focus on the method that a I was unit testing. That method was simply:

public Stream GetFileStream(string path)
{
	if (ReferenceEquals(path, null))
		throw new ArgumentNullException("path");

	if (File.Exists(path))
		return File.OpenRead(path);

	throw new FileNotFoundException(string.Format("There is no file that corresponds with the following path: {0}", path));
}

So, I went ahead and wrote the test:

[TestMethod]
[DeploymentItem(@"KesselRun.IoTests\Templates\aTemplate.txt", "Templates")]
public void GetFileStream_Returns_FileStream()
{
	var stream = _textFileIo.GetFileStream(@"Templates\aTemplate.txt");
	
	Assert.IsNotNull(stream);
	Assert.IsInstanceOfType(stream, typeof(System.IO.FileStream));
}

The only problem was, the text file aTemplate.txt was not being deployed and I was not getting an object for my FileStream. There was one thing I had forgotten to do. I had to edit the settings for the test to enable deployments. That is done by selecting the Edit Test Settings item from the Test menu (make sure you get the correct one for your test project):TestSettingsEdit
Then:

  1. click the Deployment item in the ListBox on the left;
  2. check the Enable deployment checkbox; and
  3. add the file that you want deployed (that file was actually part of my project, as you can see in the Solution Explorer part of the screen-capture below).

EnableDeployments

There are a lot of posts around the Internet where developers have written about using embedded files as deployment items for unit tests, rather than the auto-magic mechanism described in this post. For the most part, I agree with that. But in this particular scenario, where a FileStream has to be part of the method under test (and which cannot be mocked), the DeploymentItem attribute is the way to go.