Generally, when we are dealing with unit tests and static methods, we usually have to resort to various tricks in order to mock out the static dependency. The downside to this is that for the sake of unit testing some functionality, you have to add code which in my opinion is not bringing value to the production code and makes the code less readable. Sometimes, writing this extra code is unavoidable unless one resorts to frameworks such as TypeMock, Moles, etc. However, I’ve found an instance whereby mocking this extra code is unnecessary and that case arises when dealing with using LINQ to XML to read some data out (There might be some generic cases for which this applies but I wouldn’t want to pronounce myself until I’ve figured out what these are). The only “downside” is that instead of writing a unit test we would in fact be writing an integration test. I will come back to the latter and explain why I still think that in this particular case, I think it is the way to go.
So consider the following sut:
The first line is “problematic” because we are loading in an external dependency i.e. the file using a static method. Initially, I wanted to apply one of the workarounds as explained in this post. However, I was really reticent to do so and I was really dragging my foot with regards to actually implementing one of these workarounds. After reflection, I realised that what I wanted to do was to pass in a test XML file rather than the production XML file. Hence, using one of the workarounds would would have been overkill because there is much simpler and basic solution which is, instead of hardcoding the XML file path, we can simply pass the file path in as a variable:
var document = XElement.Load(_filePath);
Doing so allows us to use either the test XML file rather than the production XML file. This may seem to be the obvious solution but when people start with unit testing and they encounter static methods, the first thing that pops into their mind might be to dogmatically apply one of the workarounds provided above. However, in order to do that, the code in my workaround would have had to return an XDocument which I would have had to create in my actual test in order to write an actual unit test. This is having to write way too much code in order to test the functionality. So although my solution is actually an integration test, I think it is much better to avoid being dogmatic in this situation and forsake having a unit test for an integration test because effectively, we are testing the functionality in the latter test which is what we want to do at the end of the day. Moreover, since we have control over the test XML file, we can keep it relatively short which ensures that the test doesn’t take that long to run in any case.
For completeness’s sake, in order to set the filepath variable, I make use of constructor injection as follows: