dapr / dotnet-sdk

Dapr SDK for .NET

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WorkflowActivityContext cannot be mocked

bgelens opened this issue · comments

WorkflowActivityContext has an internal constructor only and it's not implementing an interface making it impossible? to mock.

For DaprWorkflowContext I can just use the abstract WorkflowContext so I'm not having this issue when unit testing orchestration workflow.

I suggest the same approach for WorkflowActivityContext as with WorkflowContext, make it abstract without constructor definition and derive a DaprWorkflowActivityContext. Or alternate solutions like adding an interface, make the constructor public or internal protected (that way we can derive a stub I think? by exposing internals via our csproj referencing the workflow package)

I think not being able to mock the ActivityContext is a blocker for us moving forward with Dapr Workflow

just ran into this trying to drive out the functionality of an activity with tests - this needs to be fixed.

a very ugly, horrible, no-good workaround is to use reflection:

using Xunit;
using NSubstitute;
using FluentAssertions;

// ...

    [Fact] 
    public async Task Call_activity()
    {
        YourAcvitity activity = new(/*dependencies*/);
        // since WorkflowActivityContext only has an internal constructor
        // we need to use reflection to instantiate it
        TaskActivityContext inner = Substitute.For<TaskActivityContext>();
        var context = typeof(WorkflowActivityContext)
            .GetConstructor(
                BindingFlags.NonPublic | BindingFlags.Instance,
                null,
                [typeof(TaskActivityContext)],
                null
            )
            .Invoke([inner]) as WorkflowActivityContext;

        var result = await activity
            .RunAsync(
                context,
                new TInput() // whatever your activity uses
            );

        result.Should().NotBeNull();
    }