Reputation: 964
I just finished the book The Art of Unit Testing and got a architectual question about a test pattern.
For testing if an method of an external library is used the book advises to make a wrapper with an interface. This way you make it possible to use the interface for mocking. I made an example for using the .net method File.Exists
public interface IFile
{
bool Exists(string path);
}
public class File : IFile
{
bool IFile.Exists(string path)
{
return System.IO.File.Exists(path);
}
}
[TestMethod]
[ExpectedException(typeof(System.IO.FileNotFoundException))]
public void Constructor_WithNonExistingFile_ThrowsFileNotFoundException()
{
Mock<IFile> fileMock = new Mock<IFile>();
Mock<ICompositionContainer> compositionMock
= new Mock<ICompositionContainer>();
fileMock.Setup(f => f.Exists(It.IsAny<string>())).Returns(false);
Loader<object> loader = new Loader<object>(
"testfile",
fileMock.Object,
compositionMock.Object);
}
My question about this is if this is good practice and if so, should I make interfaces and wrappers for all .net methods/classes I want to test?
Upvotes: 1
Views: 147
Reputation: 6693
Having done lot of mocking, I have come to a conclusion that mocking should be the last resort. I find mocking ties tests too much to code and generally masks untestable code. Such tests that are tied too much to implementation are considered brittle. In this case, instead of creating a wrapper interface around .NET File I/O stuff, I would just use the File I/O stuff directly. I will use the real dependency since the file system exists on the test machine. Then, in my test Setup() method, I will make sure the precondition for the test is satisfied such as creating the file. In the tear down method, I will make sure necessary clean up is done.
Sometimes, you cannot use a real dependency - for example, you are calling a service over the network. Mocks should be restricted only for such things. Even in this case you don't have to mock. You can consider using a fake - basically build an in-memory version of the service for your tests and use that version.
Upvotes: 0