How do I (or do I) unit test a specific dependency

I have a business level class that uses System.IO.File to read information from different files. For the unit test of this class, I chose to replace the dependency on the File class with a nested dependency like this:

using System.IO; public interface IFileWrapper { bool FileExists( string pathToFile ); Stream Open( string pathToFile ); } 

Now I can test my class using Mock, and everything is fine with the world. Separately, I need a specific implementation. I have the following:

 using System; using System.IO; public class FileWrapper : IFileWrapper { public bool FileExists( string pathToFile ) { return File.Exists( pathToFile ); } public Stream Open( string pathToFile ) { return File.Open( pathToFile, FileMode.Open, FileAccess.Read, FileShare.Read ); } } 

Now my business class is no longer dependent on the System.IO.File class and can be tested using the Mock from IFileWrapper. I do not see the need to test the System.IO.File class, as I assume that this has been thoroughly tested by Microsoft and proven for countless purposes.

How to check a specific FileWrapper class? Although this is a simple class (low risk), I have larger examples that follow the same approach. I can't get close to 100% code coverage (assuming it's important) without doing this.

The broader question here, I believe, is how to bridge the gap between unit testing and integration testing? Do I need to test this class or is there some kind of attribute to decorate this class in order to exclude this from the code coverage calculation.

+7
source share
3 answers

Typically, you should unit test all the production code that you write. However, due to the nature of .NET development, there will always be classes such as the Adapter class, which cannot be properly tested.

My personal rule of thumb is that if you can reduce each member in the adapter to a cyclic complexity of 1, then you can declare it a modest object .

AFAIK there is no way to exclude code from coverage reports, but you can implement your Humble Objects in separate assemblies that are exempt from coverage reports.

+7
source

In your case, testing FileWrapper is overhead. It has no role but to be a wrapper. So I would go with an attribute that excludes it from the coverage calculation.

In other cases, you may have additional logic in types such as FileWrapper, and in such cases integration testing can help you.

The broader question here, I believe, is how to bridge the gap between unit testing and integration testing?

In general, you should use these two types of testing separately. Integration testing should be at a higher level, checking the integration between the two components, so if you feel that you need to check this dependency, continue, otherwise do not write such tests. Integration tests are always more complex, work much longer and are more difficult to maintain than unit testing, so you should think twice before writing each integration test. That's why I would not say that if you write some tests for FileWrapper, it will be an Integration Test . Therefore, I want to say that there is no gap between module testing and integration, they solve different problems.

+1
source

The only purpose of your adapter class is to wrap the file system. Therefore, you can do one unit test, which checks the correctness of this behavior. Satisfying yourself, the wrapper works correctly, you can comfortably use the test double in it everywhere.

Your unit test should be very simple, but should use a specific implementation. This means that it is likely to be relatively slow (> 5 ms) and somewhat annoying installation / stall. My definition of unit test is one that runs relatively quickly and checks for small code, in this case one class.

Then you must be very careful not to add additional logic to the class, or this logic will also require a complex unit test.

The second approach is to cover this in an integration test or manual test. If this class is used everywhere, you will quickly catch any errors. Since there is little difficulty for this class, the risk of entering errors is low.

0
source

All Articles