Rajib Mahata
Rajib Mahata

Reputation: 33

How to mock DurableTaskClient in unite test and getting error in on ScheduleNewOrchestrationInstanceAsync mocking setup

I am trying to write unit test for a durable function. During that time I am facing an issue on the mocking of DurableTaskClient. I am getting an error in ScheduleNewOrchestrationInstanceAsync mocking setup .

Here is the unit test code:

    public async Task HttpStart_ValidRequest_ReturnsSuccessResponse()
    {
        // Arrange
        // Define constants
        const string functionName = "SampleFunction";
        const string instanceId = "7E467BDB-213F-407A-B86A-1954053D3C24";

        var loggerMock = new Mock<ILogger<Template>>();
        var optionsMock = new Mock<IOptions<AppConfig>>();
        var commonServiceMock = new Mock<ICommonService>();
        var ServiceMock = new Mock<IService>();

        var requestMock = new Mock<HttpRequestData>();
        var requestBody = @"{""Id"":""123""}";
        requestMock.Setup(req => req.Body).Returns(new MemoryStream(Encoding.UTF8.GetBytes(requestBody)));

      var durableClientMock = new Mock<DurableTaskClient>();

        durableClientMock.Setup(x => x.ScheduleNewOrchestrationInstanceAsync(functionName It.IsAny<object>())).
ReturnsAsync(instanceId);

        durableClientMock.Setup(client => client.ScheduleNewOrchestrationInstanceAsync(It.IsAny<string>(), requestMock.Object))
            .ReturnsAsync("instanceId123");

        var functionContextMock = new Mock<FunctionContext>();
        functionContextMock.Setup(ctx => ctx.GetLogger(It.IsAny<string>())).Returns(loggerMock.Object);

        var buildTemplate = new BuildTemplate(optionsMock.Object, commonServiceMock.Object, ServiceMock.Object);

        // Act
        var response = await buildTemplate.HttpStart(requestMock.Object, durableClientMock.Object, functionContextMock.Object);

        // Assert
        Assert.IsNotNull(response);
        Assert.AreEqual(202, response.StatusCode);
    }

I tried to setup durableClientMock in 2 different way but both are not working,

        durableClientMock.Setup(x => x.ScheduleNewOrchestrationInstanceAsync(functionName It.IsAny<object>())).
ReturnsAsync(instanceId);

        durableClientMock.Setup(client => client.ScheduleNewOrchestrationInstanceAsync(It.IsAny<string>(), requestMock.Object))
            .ReturnsAsync("instanceId123");

Showing error : Image showing the error

Upvotes: 2

Views: 1674

Answers (2)

FFranz
FFranz

Reputation: 158

As already mentioned by @Jalpa Panchals comment, you can resolve this issue by just specifying values for the optional arguments.

If you call ScheduleNewOrchestrationInstanceAsync from your production code, you normally wouldn't have to specify these, but Moq does not allow you to not set optional parameters.

Since it seems like you are using the overload that requires 3 arguments, I think you only have to set CancellationToken.None as shown below.

durableClientMock.Setup(client => client.ScheduleNewOrchestrationInstanceAsync(nameof(MyOrchestrator), It.IsAny<MyInputType>(), CancelationToken.None).Returns(<Your desired String>);

This should solve your issue.

Upvotes: 2

Rajib Mahata
Rajib Mahata

Reputation: 33

Thank you @JalpaPanchals and @FFranz. I have updated the code like that way and it's worked.

// Mock StartNewAsync method
StartOrchestrationOptions startOrchestrationOptions = new StartOrchestrationOptions()
{
    InstanceId = instanceId,
    StartAt = DateTime.UtcNow,
};
durableClientMock.
    Setup(x => x.ScheduleNewOrchestrationInstanceAsync(functionName, requestBody, startOrchestrationOptions, default)).
    ReturnsAsync(instanceId);

            // Mock CreateCheckStatusResponse method
            durableClientMock
                .Setup(x => x.CreateCheckStatusResponse(requestMock.Object, instanceId, default))
                .Returns(() =>
                {
                    var response = new Mock<HttpResponseData>(functionContextMock.Object);
                    response.SetupProperty(r => r.Headers, new HttpHeadersCollection());
                    response.SetupProperty(r => r.StatusCode);
                    response.SetupProperty(r => r.Body, new MemoryStream());
                    return response.Object;
                });

Upvotes: 0

Related Questions