首页 > 解决方案 > C#模拟单元测试GraphServiceClient

问题描述

我在使用 Moq 和 xUnit 用 C# 编写单元测试时遇到问题。

在我的服务中,我有以下代码:

var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential);


return (await graphClient.Users.Request().Filter($"displayName eq '{mobilePhone}'").GetAsync()).FirstOrDefault();

但我不知道模拟GraphClient函数的方法:

graphClient.Users.Request().Filter($"displayName eq '{mobilePhone}'").GetAsync()).FirstOrDefault();

标签: c#azuremoqxunit

解决方案


根据您的用例和现有代码库,您还可以在构造函数调用中为两个接口提供一些空存根,并使用覆盖虚拟函数的能力。如果您使用文档中提供的 Moq 等模拟框架,这会派上用场:

// Arrange
var mockAuthProvider = new Mock<IAuthenticationProvider>();
var mockHttpProvider = new Mock<IHttpProvider>();
var mockGraphClient = new Mock<GraphServiceClient>(mockAuthProvider.Object, mockHttpProvider.Object);

ManagedDevice md = new ManagedDevice
{
    Id = "1",
    DeviceCategory = new DeviceCategory()
    {
        Description = "Sample Description"
    }
};

// setup the calls
mockGraphClient.Setup(g => g.DeviceManagement.ManagedDevices["1"].Request().GetAsync(CancellationToken.None)).ReturnsAsync(md).Verifiable();

// Act
var graphClient = mockGraphClient.Object;
var device = await graphClient.DeviceManagement.ManagedDevices["1"].Request().GetAsync(CancellationToken.None);

// Assert
Assert.Equal("1",device.Id);

通过使用这种方法,您不必为在线上完成的具体 HTTP 请求而烦恼。相反,您只需使用参数覆盖(嵌套)方法调用,并在没有序列化/反序列化步骤的情况下定义返回的对象。另请注意,在模拟中,您可以使用 egIt.IsAny<string>()和类似的构造来定义您是否需要精确的参数检查或其他东西。


推荐阅读