Search code examples
c#unit-testingasp.net-coreazure-functionsmstest

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


Solution

  • 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.