Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using IDataProtectionProvider in test project?

When using IDataProtectionProvider in a Web API, the IoC container is configured with AddDataProtection (services.AddDataProtection();) and enables the use of DI to retrieve a IDataProtectionProviderin a service as such:

private readonly IDataProtectionProvider _dataProtectionProvider;

public CipherService(IDataProtectionProvider dataProtectionProvider)
{
    _dataProtectionProvider = dataProtectionProvider;
}

If I would like to test my CipherService (in my case using Xunit), I will not be able to make this work without using DI, so my question is;

Q: How can I use DI or otherwise make IDataProtectionProvider in a test project?

like image 250
Marcus Avatar asked Aug 07 '17 11:08

Marcus


2 Answers

Here how I did it using Moq framework:

Mock<IDataProtector> mockDataProtector = new Mock<IDataProtector>();
mockDataProtector.Setup(sut => sut.Protect(It.IsAny<byte[]>())).Returns(Encoding.UTF8.GetBytes("protectedText"));
mockDataProtector.Setup(sut => sut.Unprotect(It.IsAny<byte[]>())).Returns(Encoding.UTF8.GetBytes("originalText"));

Mock<IDataProtectionProvider> mockDataProtectionProvider = new Mock<IDataProtectionProvider>();
mockDataProtectionProvider.Setup(s => s.CreateProtector(It.IsAny<string>())).Returns(mockDataProtector.Object);

And where I need to pass in the IDataProtectionProvider, I use:

mockDataProtectionProvider.Object

For an integration test scenario, where you want a real DataProtectionProvider, you can use the following MSDN Documentation article.

Hope this helps.

like image 55
Artak Avatar answered Nov 11 '22 12:11

Artak


EphemeralDataProtectionProvider can be used in a unit testing scenario as it generates a random secret for each instance.

Example:

var dataProtectionProvider = new EphemeralDataProtectionProvider();

var service = new CipherService(dataProtectionProvider);

// test as usual

This was specifically provided by Microsoft for your exact use-case.

There are scenarios where an application needs a throwaway IDataProtectionProvider. For example, the developer might just be experimenting in a one-off console application, or the application itself is transient (it's scripted or a unit test project). To support these scenarios the Microsoft.AspNetCore.DataProtection package includes a type EphemeralDataProtectionProvider. This type provides a basic implementation of IDataProtectionProvider whose key repository is held solely in-memory and isn't written out to any backing store.

like image 21
Matthew Avatar answered Nov 11 '22 12:11

Matthew