C# 如何使用Azure密钥库进行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();)我会得到以下结果: "

我需要模拟密钥库的端点,以便知道我是否调用函数获取密钥库一次

为了进行测试,我正在使用C#和Moq(框架)开发这个

界面如下所示:

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;