Moq - VianneyDoleans/Teia-Tests-Documentation GitHub Wiki
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 ofIEncryptionService
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.
First, the declaration.
var encryptionMock = new Mock<IEncryptionService>();
With this line, you have a mock
of IEncryptionService
.
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 typebyte[]
, 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.
builder.RegisterInstance(encryptionMock.Object);
-
encryptionMock.Object
return an instantiated object of typeIEncryptionService
. 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 realIEncryptionService
.
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).