How do you do unit testing with Dapr?
Asked Answered
S

2

8

I've got a class that I'm trying to unit test but it uses a DaprClient object (from the SDK), which doesn't work in my unit test envioronment. I would like to create a mock and use that instead but the only interface DaprClient implements is IDisposable.

Is there a way to mock DaprClient for unit tests?

The only solution I can think of would be to wrap DaprClient in a class with an interface and use this wrapper everywhere. This just feels really messy and will need the wrapper to be updated every time I want to use a new method on the DaprClient.

I'm open to other solutions which might bypass the problem but I'd prefer a simple replace with mock type approach.

I'm using .Net 5, xUnit and Moq in Visual Studio 2019 on Windows (although some team members use Macs so it needs to work on both platforms).

In this particular instance, I'm using the DaprClient.GetBulkSecretAsync method but I'd like a solution that I can use elsewhere, if possible.

Snead answered 13/7, 2021 at 12:29 Comment(4)
https://mcmap.net/q/1472198/-a-simple-way-to-convert-a-static-class-to-regular-class-in-legacy-applications-to-enable-mocking - See the list of unconstrained frameworks that will helpCyruscyst
this might helpIndustrious
This is the reality of working with C#. I'm finding that no external dependencies, not even ones that are written by the C# team themselves have externally exposed interfaces for mocking. Wrapper client and interface is the only sane solution. I assume you've come to that conclusion already and just airing grievance. Let me validate that: its a poor state of affairs, I feel the same. Shame on C# team for not learning lessons from mistakes of other languages.Aalii
@YarekT It's not really my experience of C#. I've found most of the MS libraries are designed with unit testing in mind. They're not always well documented, but a lot of the areas I've had issues with being unable to create an object in a mock because it involves internal stuff, they provide factory classes for this purpose.Snead
I
2
using Dapr.Client;
using FluentAssertions;
using Moq;

[TestMethod("How to mock GetBulkSecretAsync - 68362431")]
public async Task TestMethod1()
{
    //arrange
    var daprClient = new Mock<DaprClient>();
    var exampleService = new ExampleService(daprClient.Object);

    daprClient.Setup(d => d.GetBulkSecretAsync("my-store",
        It.IsAny<IReadOnlyDictionary<string, string>>(),
        It.IsAny<CancellationToken>()))
        .ReturnsAsync(new Dictionary<string, Dictionary<string, string>>
        {
            {
                "example",
                new Dictionary<string, string>
                {
                    { "i don't understand the builk API (yet)", "some value" }
                }
            }
        });

    //act
    var actual = await exampleService.GetBulkSecrets("my-store");

    //assert
    actual.Should().BeEquivalentTo(new Dictionary<string, Dictionary<string, string>>
    {
        {
            "example",
            new Dictionary<string, string>
            {
                { "i don't understand the builk API (yet)", "some value" }
            }
        }
    });
}

references:


but I'd like a solution that I can use elsewhere, if possible

In general, we need to use the abstract methods defined in the DaprClient.

Industrious answered 4/10, 2022 at 13:33 Comment(0)
B
1

You need to use one of two options

  • a mocking framework that uses shims as they make a mock object based on a concrete class. Fakes from visual studio enterprise and other paid frameworks have it. Fewer opensource frameworks have the option. Pose is one with the option perhaps via Shimmy
  • wrap the class in a class that uses a interface you can use for mocking (the worst possibility)
Basilbasilar answered 5/9, 2021 at 4:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.