C# 如何使用Azure密钥库进行Moq单元测试
我需要模拟密钥库的端点,以便知道我是否调用函数获取密钥库一次 为了进行测试,我正在使用C#和Moq(框架)开发这个 界面如下所示:C# 如何使用Azure密钥库进行Moq单元测试,c#,azure,unit-testing,moq,azure-keyvault,C#,Azure,Unit Testing,Moq,Azure Keyvault,我需要模拟密钥库的端点,以便知道我是否调用函数获取密钥库一次 为了进行测试,我正在使用C#和Moq(框架)开发这个 界面如下所示: public interface IKeyVaultConnection { string GetKeyVaultValue(string variableName); } 因为没有提供端点 如果我取消注释最后一行(mock.Verify(x=>x.GetKeyVaultValue(It.IsAny()),Times.Once();)我会得到以下结果: "
public interface IKeyVaultConnection
{
string GetKeyVaultValue(string variableName);
}
因为没有提供端点
如果我取消注释最后一行(mock.Verify(x=>x.GetKeyVaultValue(It.IsAny()),Times.Once();)
我会得到以下结果:
"Expected invocation on the mock once, but was 0 times:
x => x.GetKeyVaultValue(It.IsAny<string>())"
“预期对模拟调用一次,但调用次数为0次:
x=>x.GetKeyVaultValue(It.IsAny())”
如果您认为您的类只是一个谦逊的包装器,这样其他类就可以依赖IsomethingAtReturnsValue
而不知道KeyVaultClient
,那么模仿KeyVaultClient
就没有必要了。我们只需要走这么远。我们不需要对所依赖的框架类进行单元测试
换句话说,我们是否需要验证这一点
keyVaultClient.GetSecretAsync($"{endpointKeyVault}/secrets/{ keyName }")
…实际上调用端点来获取秘密?是的。这就是KeyVaultClient.GetSecretAsync(string)
所做的。如果测试失败,我们能做什么?我们修不了那门课。类似地,如果我们沿着这条路走到它的逻辑结论,我们将不得不测试各种各样的东西。当我们创建一个列表
并添加一个字符串时,它真的被添加了吗?我们不测试这些东西,因为它们已经测试过了,所以可以合理地假设它们按预期工作
对于这一点,一个好的测试应该是一个集成测试,它验证您的类是否达到了预期的效果。或者,如果另一个类依赖于此,您可以为该类编写一个集成测试,如果您无法从密钥库检索任何内容,该测试将失败。但这不需要任何嘲弄
不进行类的单元测试的一个好处是最小化它,使它实际上除了调用内部类之外什么都不做。在这种情况下,您可以将public
和private
方法折叠为一个public
方法,也可以再折叠一个以提供async
选项:
public async Task<string> GetSecretValueAsync(string keyName)
{
return await keyVaultClient.GetSecretAsync($"{endpointKeyVault}/secrets/{ keyName }");
}
public string GetSecretValue(string keyName) => GetSecretValueAsync(keyName).Result;
public异步任务GetSecretValueAsync(字符串keyName)
{
返回wait-keyVaultClient.GetSecretAsync($“{endpointKeyVault}/secrets/{keyName}”);
}
公共字符串GetSecretValue(字符串keyName)=>GetSecretValueAsync(keyName);
现在更明显的是:这个类本身并没有做任何需要单元测试的事情。它的有用用途是将
KeyVaultClient
调整到您的界面-IKeyVaultConnection
,这样其他类就不会直接依赖于KeyVaultClient
“一些错误”-您可以更具体一些吗?@stuartd编辑过,但有点错误,例如,您没有提供端点等等…请共享完整的测试,对于sut,调用也是如此。。。什么是IKeyVaultWrapper
?顺便说一句,您不应该返回It.IsAny()
它将为null
。Moq不知道返回任何字符串,这是合理的,不是吗……”预期对模拟调用一次,但是0次“好吧,在您提供的代码中,您没有调用它,所以这是预期的?您正在测试的类是?我认为问题在于您使用了.Returns(It.IsAny())
,这意味着该方法将返回null,然后您的sut类实际上会对此抱怨。。。
"Expected invocation on the mock once, but was 0 times:
x => x.GetKeyVaultValue(It.IsAny<string>())"
keyVaultClient.GetSecretAsync($"{endpointKeyVault}/secrets/{ keyName }")
public async Task<string> GetSecretValueAsync(string keyName)
{
return await keyVaultClient.GetSecretAsync($"{endpointKeyVault}/secrets/{ keyName }");
}
public string GetSecretValue(string keyName) => GetSecretValueAsync(keyName).Result;