CosmosDB 中的模拟 ItemResponse

Sar*_*mad 5 c# moq xunit azure .net-core

我正在使用 xUnit 中的 Moq 为涉及 CosmosDB 的服务编写单元测试。有一个从 CosmosDBGetVehicleInfo返回的方法ItemResponse<VehicleInfo>。由于ItemResponse有一个受保护的构造函数,所以我无法更新它。因此,我嘲笑调用者方法并做

var responseMock = new Mock<ItemResponse<VehicleInfo>>();
responseMock.Setup(x => x.Resource).Returns(expectedItem); //expectedItem is of VehicleInfo type
cosmoRepoServiceStub.Setup(service => service.GetVehicleInfo("a1", "a2").Result).Returns(responseMock.Object);
Run Code Online (Sandbox Code Playgroud)

我面临的问题是,当GetVehicleInfo如下调用时,它null总是返回。我希望它返回ItemResponse<VehicleInfo>其中Resource将包含expectedItem.

ItemResponse<VehicleInfo> response = await _cosmosRepo.GetVehicleInfo(plate, country);
if (response == null){ //... }
Run Code Online (Sandbox Code Playgroud)

Pet*_*ala 5

您应该像这样设置您的 cosmoRepoServiceStub:

cosmoRepoServiceStub
    .Setup(service => service.GetVehicleInfo(It.IsAny<string>(), It.IsAny<string>()))
    .ReturnsAsync(responseMock.Object);
Run Code Online (Sandbox Code Playgroud)
  • GetVehicleInfo参数应该是设置方法中的任何字符串
  • 请不要调用.Result方法选择器内部ReturnsAsync

或者,如果您确实需要预测"a1"第一个参数,则将其定义为

const StringComparison comparison = StringComparison.OrdinalIgnoreCase;
cosmoRepoServiceStub
    .Setup(service => service.GetVehicleInfo(
       It.Is<string>(param1 => string.Equals(param1, "a1", comparison), 
       It.Is<string>(param1 => string.Equals(param1, "a2", comparison)))
    .ReturnsAsync(responseMock.Object);
Run Code Online (Sandbox Code Playgroud)

更新 #1反映评论

为什么It.IsAny有效而"a1"无效?

Moqobject.Equals在底层使用use来Setup根据实际调用的参数来检查 的参数。

这意味着值类型和字符串的比较基于它们的值(而不是基于它们的引用)。

因此,在您的特定情况下,这意味着分别包含platecountry不包含a1a2字符串。

简而言之,我应该工作,但作为一般经验法则

  • 让你的Setup内容尽可能通用
  • 让您的Verify内容尽可能具体