在测试项目中使用 IDataProtectionProvider?

Using IDataProtectionProvider in test project?

在 Web API 中使用 IDataProtectionProvider 时,IoC 容器配置为 AddDataProtection (services.AddDataProtection();) 并允许使用 DI 检索 IDataProtectionProvider在这样的服务中:

private readonly IDataProtectionProvider _dataProtectionProvider;

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

如果我想测试我的 CipherService(在我使用 Xunit 的情况下),我将无法在不使用 DI 的情况下完成这项工作,所以我的问题是;

问:如何在测试项目中使用 DI 或以其他方式制作 IDataProtectionProvider

这里是我如何使用 Moq 框架完成的:

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);

在需要传入 IDataProtectionProvider 的地方,我使用:

mockDataProtectionProvider.Object

对于集成测试场景,您需要一个真正的 DataProtectionProvider,您可以使用以下 MSDN Documentation 文章。

希望对您有所帮助。

EphemeralDataProtectionProvider 可用于单元测试场景,因为它为每个实例生成一个随机秘密。

示例:

var dataProtectionProvider = new EphemeralDataProtectionProvider();

var service = new CipherService(dataProtectionProvider);

// test as usual

这是 Microsoft 专门为您的具体用例提供的。

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.