如何模拟 Microsoft Graph API SDK 客户端? [英] How to mock Microsoft Graph API SDK Client?

查看:105
本文介绍了如何模拟 Microsoft Graph API SDK 客户端?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的项目中使用了 Microsoft Graph SDK 来调用图形 API,为此我需要使用 GraphServiceClient.要使用 GraphServiceClient,我必须添加一些辅助类,其中 SDKHelper 是具有 GetAuthenticatedClient() 方法的静态类.由于被测方法与静态的 SDKHelper 紧密耦合,因此我创建了一个服务类并注入了依赖项.

I have used Microsoft Graph SDK in my project to call graph API, for this I need to use GraphServiceClient. To use GraphServiceClient, i have to add some helper classes, in which SDKHelper is a static class which has GetAuthenticatedClient() method. Since method under test is tightly coupled to SDKHelper which is static, so I have created a service class and injected the dependency.

下面是控制器和方法,

public class MyController
{
    private IMyServices _iMyServices { get; set; }

    public UserController(IMyServices iMyServices)
    {
        _iMyServices = iMyServices;
    }
    public async Task<HttpResponseMessage> GetGroupMembers([FromUri]string groupID)
    {
        GraphServiceClient graphClient = _iMyServices.GetAuthenticatedClient();
        IGroupMembersCollectionWithReferencesPage groupMembers = await _iMyServices.GetGroupMembersCollectionWithReferencePage(graphClient, groupID);
        return this.Request.CreateResponse(HttpStatusCode.OK, groupMembers, "application/json");
    }
}

服务类,

public class MyServices : IMyServices
{
    public GraphServiceClient GetAuthenticatedClient()
    {
        GraphServiceClient graphClient = new GraphServiceClient(
            new DelegateAuthenticationProvider(
                async (requestMessage) =>
                {
                    string accessToken = await SampleAuthProvider.Instance.GetAccessTokenAsync();
                    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
                    requestMessage.Headers.Add("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"");
                }));
        return graphClient;
    }

    public async Task<IGraphServiceGroupsCollectionPage> GetGraphServiceGroupCollectionPage(GraphServiceClient graphClient)
    {
        return await graphClient.Groups.Request().GetAsync();
    }
}

我在为上述服务类方法编写单元测试用例时遇到了挑战,以下是我的单元测试代码:

I am having challenge in writing Unit Test Case for the above service class methods, Below is my Unit Test Code:

public async Task GetGroupMembersCollectionWithReferencePage_Success()
{
    GraphServiceClient graphClient = GetAuthenticatedClient();
    IGraphServiceGroupsCollectionPage groupMembers = await graphClient.Groups.Request().GetAsync();

    Mock<IUserServices> mockIUserService = new Mock<IUserServices>();
    IGraphServiceGroupsCollectionPage expectedResult = await mockIUserService.Object.GetGraphServiceGroupCollectionPage(graphClient);
    Assert.AreEqual(expectedResult, groupMembers);
}

在上面的测试用例中,第 4 行抛出异常 -消息:Connect3W.UserMgt.Api.Helpers.SampleAuthProvider"的类型初始值设定项引发异常.内部异常消息:值不能为空.参数名称:格式

In Above Test case line number 4 throws an exception - Message: The type initializer for 'Connect3W.UserMgt.Api.Helpers.SampleAuthProvider' threw an exception. Inner Exception Message: Value cannot be null. Parameter name: format

谁能建议我如何使用 MOQ 来模拟上面的代码或任何其他方法来完成测试用例?

Can anyone suggest me how to use MOQ to mock above code or any other method to complete test case for this ?

推荐答案

不要嘲笑你不拥有的东西.GraphServiceClient 应被视为第 3 方依赖项,并应封装在您控制的抽象之后

Do not mock what you do not own. GraphServiceClient should be treated as a 3rd party dependency and should be encapsulated behind abstractions you control

您尝试这样做,但仍然存在实施问题.

You attempted to do that but are still leaking implementation concerns.

服务可以简化为

public interface IUserServices {

    Task<IGroupMembersCollectionWithReferencesPage> GetGroupMembers(string groupID);

}

和实现

public class UserServices : IUserServices {
    GraphServiceClient GetAuthenticatedClient() {
        var graphClient = new GraphServiceClient(
            new DelegateAuthenticationProvider(
                async (requestMessage) =>
                {
                    string accessToken = await SampleAuthProvider.Instance.GetAccessTokenAsync();
                    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
                    requestMessage.Headers.Add("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"");
                }));
        return graphClient;
    }

    public Task<IGroupMembersCollectionWithReferencesPage> GetGroupMembers(string groupID) {
        var graphClient = GetAuthenticatedClient();
        return graphClient.Groups[groupID].Members.Request().GetAsync();
    }
}

这将导致控制器也被简化

Which would result in the controller being simplified as well

public class UserController : ApiController {
    private readonly IUserServices service;

    public UserController(IUserServices myServices) {
        this.service = myServices;
    }

    public async Task<IHttpActionResult> GetGroupMembers([FromUri]string groupID) {
        IGroupMembersCollectionWithReferencesPage groupMembers = await service.GetGroupMembers(groupID);
        return Ok(groupMembers);
    }
}

现在为了测试控制器,您可以轻松地模拟抽象以使其按预期运行,以便完成测试,因为控制器与 GraphServiceClient 3rd 方依赖项完全分离,并且控制器可以进行隔离测试.

Now for testing of the controller you can easily mock the abstractions to behave as expected in order to exercise the test to completion because the controller is completely decoupled from the GraphServiceClient 3rd party dependency and the controller can be tested in isolation.

[TestClass]
public class UserControllerShould {
    [TestMethod]
    public async Task GetGroupMembersCollectionWithReferencePage_Success() {
        //Arrange
        var groupId = "12345";
        var expectedResult = Mock.Of<IGroupMembersCollectionWithReferencesPage>();
        var mockService = new Mock<IUserServices>();
        mockService
            .Setup(_ => _.GetGroupMembers(groupId))
            .ReturnsAsync(expectedResult);

        var controller = new UserController(mockService.Object);

        //Act
        var result = await controller.GetGroupMembers(groupId) as System.Web.Http.Results.OkNegotiatedContentResult<IGroupMembersCollectionWithReferencesPage>;

        //Assert
        Assert.IsNotNull(result);
        var actualResult = result.Content;
        Assert.AreEqual(expectedResult, actualResult);
    }
}

这篇关于如何模拟 Microsoft Graph API SDK 客户端?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆