A Simple Moq Example - Connecting to a Database and Processing Files

I am new to unit testing. Although I can do a simple unit test, it's hard for me to understand the dependency injection part. I have 2 scenarios where I could not create a test

  • Database connection
  • Log File Processing

Although I searched the Internet and I could not find a simple example to follow and implement these ridicule.

Can Moq supports a specific class, or do I need to change my entire implementation to a virtual one for unit testing. Any sample code or link for example code is much appreciated

+4
source share
1 answer

First of all, Moq does not support mocking specific classes. Only abstract classes and interfaces can be mocked. However, it is not as difficult as it seems. As an example, consider processing a log file.

Suppose you start with the following specific logging class:

public class Log { public void WriteToLog(string message) { ... } } 

We have another class that uses this Log class for logging:

 public class LogGenerator { public void Foo() { ... var log = new Log(); log.WriteToLog("my log message"); } } 

The problem with the Foo method testing module is that you have no control over the creation of the Log class. The first step is to apply a control inversion , where the caller decides which instances are used:

 public class LogGenerator { private readonly Log log; public LogGenerator(Log log) { this.log = log; } public void Foo() { ... this.log.WriteToLog("my log message"); } } 

Now we are one step closer to successful unit testing, as our unit test can select a Log instance for logging. The final step now is to make the Log mockable class we could do by adding an ILog interface that is implemented by Log and has a LogGenerator that depends on this interface:

 public interface ILog { void WriteToLog(string message); } public class Log : ILog { public void WriteToLog(string message) { ... } } public class LogGenerator { private readonly ILog log; public LogGenerator(ILog log) { this.log = log; } public void Foo() { ... this.log.WriteToLog("my log message"); } } 

Now we can use Moq in our unit test to create a mockup of an object that implements ILog :

 public void FooLogsCorrectly() { // Arrange var logMock = new Mock<ILog>(); var logGenerator = new LogGenerator(logMock.Object); // Act logGenerator.Foo(); // Assert logMock.Verify(m => m.WriteToLog("my log message")); } 
+9
source

Source: https://habr.com/ru/post/1491876/


All Articles