使用Dapr如何进行单元测试?

6
我有一个类需要进行单元测试,但它使用了一个DaprClient对象(来自SDK),在我的单元测试环境中无法工作。我想创建一个模拟对象并代替它,但是DaprClient仅实现IDisposable接口。
有没有办法为单元测试模拟DaprClient?
我能想到的唯一解决方案是将DaprClient封装在一个具有接口的类中,并在所有地方使用此包装器。这感觉很混乱,并且每当我想要使用DaprClient上的新方法时都需要更新此包装器。
我愿意尝试其他解决方案,可以绕过该问题,但我更喜欢简单的替换为模拟类型的方法。
我在Windows上使用Visual Studio 2019的.Net 5、xUnit和Moq(尽管一些团队成员使用Mac,因此需要在两个平台上运行)。
在这个特定的例子中,我正在使用DaprClient.GetBulkSecretAsync 方法,但如果可能的话,我希望有一个可在其他地方使用的解决方案。

1
查看无约束框架列表,这将有助于您进行编程:https://stackoverflow.com/a/68959562/5045688 - Alexander Petrov
请参考以下链接:https://github.com/dapr/dotnet-sdk/issues/774#issuecomment-966721169 - spottedmahn
这就是使用C#的现实。我发现,即使是由C#团队自己编写的外部依赖,也没有对外公开的接口可以进行模拟。包装客户端和接口是唯一明智的解决方案。我猜你已经得出了这个结论,只是在抱怨而已。让我验证一下:这是一个糟糕的情况,我也有同感。C#团队应该从其他语言的错误中吸取教训,真是可惜。 - Yarek T
@YarekT 这并不是我对C#的经验。我发现大多数微软库都是以单元测试为目标设计的。虽然它们的文档不总是很完善,但在我遇到无法在模拟中创建对象的问题时,它们提供了专门用于此目的的工厂类。 - Mog0
2个回答

1

你需要使用以下两个选项之一:

  • 一个使用 shims 的模拟框架,因为它们可以基于具体类创建模拟对象。Visual Studio Enterprise 和其他付费框架的 Fakes 具有该功能。较少的开源框架具有此选项。Pose 是其中一个,可能通过 Shimmy 实现。
  • 将类包装在使用接口的类中,以便您可以用于模拟(最糟糕的可能性)。

1
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" }
            }
        }
    });
}

参考资料:


但我希望有一个可以在其他地方使用的解决方案,如果可能的话

一般来说,我们需要使用 DarpClient 中定义的抽象方法


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接