Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I MOQ the System.IO.FileInfo class... or any other class without an interface?

I am writing a number of unit tests for a logger class I created and I want to simulate the file class. I can't find the interface that I need to use to create the MOQ... so how do you successfully MOQ a class without an interface?

It also isn't clear to me how I can use dependency injection without having an interface available:

private FileInfo _logFile;  public LogEventProcessorTextFile(FileInfo logFile) {     _logFile = logFile; } 

When I really want to do something like this (note IFileInfo instead of FileInfo):

private IFileInfo _logFile;  public LogEventProcessorTextFile(IFileInfo logFile) {     _logFile = logFile; } 
like image 880
InvertedAcceleration Avatar asked Oct 17 '09 16:10

InvertedAcceleration


People also ask

What is System IO FileInfo?

FileInfo Class (System.IO)Provides properties and instance methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of FileStream objects. This class cannot be inherited.

What can be mocked with MOQ?

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces. However, there are a few limitations you should be aware of. The classes to be mocked can't be static or sealed, and the method being mocked should be marked as virtual.


2 Answers

Design your code so that instead of accessing the FileInfo class directly, access an interface (named for example IFileInfo) with the same capabilities. In production code you will use a class that just delegates all its functionality to the system FileInfo class, but for unit testing you can mock the interface.

For example, in an application I made that acted differently depending on the current date, I declared the following interface:

interface IDateTimeProvider {     DateTime Today(); } 

And the production class was just:

class DateTimeProvider : IDateTimeProvider {     public DateTime Today()     {         return DateTime.Today;     } } 

You can complement this approach with the usage of a dependency injection engine to decide whether a real class or a mock should be used in each case.

like image 118
Konamiman Avatar answered Sep 21 '22 21:09

Konamiman


Use SystemWrapper, a library which provides interfaces and mockable wrappers classes for many .NET classes which don't implement interfaces themselves.

like image 45
Wim Coenen Avatar answered Sep 19 '22 21:09

Wim Coenen