SJC
SJC

Reputation: 3007

Unit Testing Graph SDK PageIterator

I am creating a service that uses Microsofts Graph SDK which has a method for retrieving all applications from Active Directory. Originally I wrote the method with only a single page in mind and successfully mocked out the call in unit tests like below.

Method

public async Task<IList<Application>> GetAllApplicationsAsync()
{
    var applicationFirstPage = await _graphServiceClient.Applications
            .Request()
            .GetAsync();

    return applicationFirstPage;
}

Unit Test

[Test]
public async Task GetAllApplicationsAsync_NoApplications_ReturnsEmptyAsync()
{
    // Arrange
    var graphServiceClientMock = new Mock<IGraphServiceClient>();

    // Create an empty page of applications
    GraphServiceApplicationsCollectionPage page = new GraphServiceApplicationsCollectionPage { };

    graphServiceClientMock.Setup(m => m.Applications.Request().GetAsync()).ReturnsAsync(() => page);
    var graphClient = new GraphClient(graphServiceClientMock.Object);

    // Act
    var apps = await graphClient.GetAllApplicationsAsync();

    // Assert
    Assert.That(apps, Is.Empty);
}

I then proceeded to extend the method from the default query and loop through all pages to get a list of all applications. I used PageIterator as outlined in the docs. When I went to update the unit tests I've struggled to adapt them to include PageIterator.

Calling await pageIterator.IterateAsync(); throws a null ref exception, and I cannot think of how I'd mock or get around that.

Extended Method

public async Task<IList<Application>> GetAllApplicationsAsync()
{
    var applicationFirstPage = await _graphServiceClient.Applications
            .Request()
            .GetAsync();

    List<Application> applications = new List<Application>();
    var pageIterator = PageIterator<Application>
        .CreatePageIterator(_graphServiceClient, applicationFirstPage, (a) =>
        {
            applications.Add(a);
            return true;
        });

    await pageIterator.IterateAsync();

    return applications;
}

I'd appreciate any help or advice on how to cover this method with unit tests. Thanks in advance.

Upvotes: 0

Views: 1303

Answers (1)

user2250152
user2250152

Reputation: 20725

pageIterator.IterateAsync() internally access page.AdditionalData but AdditionalData are not initialized in the constructor of GraphServiceApplicationsCollectionPage.

You have to initialize AdditionalData.

GraphServiceApplicationsCollectionPage page = new GraphServiceApplicationsCollectionPage 
{
    AdditionalData = new Dictionary<string, object>()
};

PageIterator

Upvotes: 3

Related Questions