Moq - VianneyDoleans/Teia-Tests-Documentation GitHub Wiki

Moq

IEncryptionService

This moq example comes from Teia.

IEncryptionService is a Teia's service that enables to encrypt and decrypt data for Teia's database (security).

By doing a mock of IEncryptionService inside the test :

  • No need to declare and implement IEncryptionService's dependencies. We just re-implement what we need in order to run your unit tests and that's all.
  • Your unit tests are not dependent of IEncryptionService. If the code of IEncryptionService have some bugs or errors, currently or in the future, it will not modify the output of the tests we are realizing.

The code :

var encryptionMock = new Mock<IEncryptionService>();
encryptionMock.Setup(x => x.Encode(It.IsAny<byte[]>())).Returns<byte[]>(x => 
{
    var array = x.ToList();
    array.Add(17);
    return array.ToArray();
});
encryptionMock.Setup(x => x.Decode(It.IsAny<byte[]>())).Returns<byte[]>(x =>
{
    var array = x.ToList();
    if (x.Length > 0) 
        array.RemoveAt(x.Length - 1);
    return array.ToArray();
});
builder.RegisterInstance(encryptionMock.Object);

In this example, you can see how Moq works.

Declaration

First, the declaration.

var encryptionMock = new Mock<IEncryptionService>();

With this line, you have a mock of IEncryptionService.

Mock comportment

encryptionMock.Setup(x => x.Encode(It.IsAny<byte[]>())).Returns<byte[]>(x => 
{
    var array = x.ToList();
    array.Add(17);
    return array.ToArray();
});

This few line can be resume by :

  • "When byte[] Encode(byte[] data); is called and receive any argument of type byte[], you run this piece of code I've realized, and return the result."

By doing this, you implement the comportment of byte[] Encode(byte[] data); for you mock IEncryptionService.

For reminder : A mock is an empty object, it is fill with blank. So in order to be used inside your unit test, you will have to redefine the comportment of some functions (only the ones used). It's not a problem if the re-implementation mock is simple, it's not the part you're testing, you just need something to work in order to run your test.

Mock object

builder.RegisterInstance(encryptionMock.Object);
  • encryptionMock.Object return an instantiated object of type IEncryptionService. This is your mock.
  • This object is empty, and only have the two methods we've implemented, "Encode" and "Decode".
  • We can know used this IEncryptionService object, and make the tests believe it's the real IEncryptionService.

Autofac and final utilization

builder.RegisterInstance() from builder.RegisterInstance(encryptionMock.Object); is registering your mock as the IEncryptionService injection instance, and so now, when we will do inside your unit test for example :

[Test]
public void AddEncryptPassword()
{
    var record = GetTestPasswordRecord();
    var password = record.Password;
    _oAuth2ConfigService.Add(ref record);

    Assert.True(record.Password != password);
}

_oAuth2ConfigService.Add(ref record); will called your Encode method of IEncryptionService, return a result, and so we could verify that _oAuth2ConfigService.Add() encrypts the data during its process (security).

⚠️ **GitHub.com Fallback** ⚠️