【问题标题】:Using IDataProtectionProvider in test project?在测试项目中使用 IDataProtectionProvider?
【发布时间】:2017-08-07 11:07:48
【问题描述】:

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

private readonly IDataProtectionProvider _dataProtectionProvider;

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

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

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

【问题讨论】:

  • 那么为什么不直接模拟依赖并将其注入到依赖类中呢?
  • 因为这是一个集成测试。
  • 查看source code 并查看需要模拟/存根/伪造的依赖项

标签: c# encryption asp.net-core .net-core integration-testing


【解决方案1】:

我是如何使用 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 文章。

希望这会有所帮助。

【讨论】:

  • 如果您使用采用字符串而不是字节数组的扩展保护方法,它不起作用,知道吗?
  • 这对我不起作用,因为它是一个不运动的表达式。 (此处:DataProtectionCommonExtensions.CreateProtector)不得用于设置/验证表达式。你能解释一下你是如何解决这个问题的吗?
【解决方案2】:

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

例子:

var dataProtectionProvider = new EphemeralDataProtectionProvider();

var service = new CipherService(dataProtectionProvider);

// test as usual

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

在某些情况下,应用程序需要一次性 IDataProtectionProvider。例如,开发人员可能只是在试验一次性控制台应用程序,或者应用程序本身是临时的(它是脚本或单元测试项目)。为了支持这些场景,Microsoft.AspNetCore.DataProtection 包包含一个 EphemeralDataProtectionProvider 类型。此类型提供了 IDataProtectionProvider 的基本实现,其密钥存储库仅保存在内存中,不会写入任何后备存储。

【讨论】:

  • 我相信这应该是公认的答案,因为它提供了一种在测试的“安排/准备”阶段保护/取消保护数据的方法,然后在测试本身中应用/测试相反的操作.无论如何,感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多