如何在 Azure Function 应用程序中模拟库依赖项,而不将库添加为测试项目的依赖项?

问题描述 投票:0回答:1

我想使用 Moq 测试 Azure Function 应用程序 (.NET 8)。

该解决方案由两个项目组成:

  • 资产治理(来源)
  • AssetGovernace.Tests(测试)

虽然我可以轻松模拟

IApplicationService
IApplicationNotificationRepository
IQueueService
,例如:

var _applicationServiceMock = new Mock<IApplicationService>();

我不知道如何模拟

IMapper
(AutoMapper)、
IConfiguration
ILogger
,而不包含
AssetGovernance
AssetGovernance.Tests
的相关包依赖项以使接口可用。这是正确的做法吗?然后我必须保持源项目和测试项目之间的包版本同步。

在查看此示例存储库时,我没有看到测试项目复制了源项目的所有依赖项,但它也没有解决我的问题。

https://github.com/Azure-Samples/azure-functions-code-testing-sample/tree/main

我应该如何在 Azure Function 应用程序中模拟这些框架和库依赖项?

ApplicationGovernanceService
班级:

public class ApplicationGovernanceService(
    IApplicationService applicationService,
    IApplicationNotificationRepository applicationNotificationRepository,
    IQueueService queueService,
    IMapper mapper,
    IConfiguration configuration,
    ILogger<ApplicationGovernanceService> logger)
    : IApplicationGovernanceService

IApplicationGovernanceService
界面:

public interface IApplicationGovernanceService
{
    public Task CheckApplicationOwnership(CancellationToken cancellationToken = default);
}

奖励:有没有办法在测试项目中进行依赖注入?

c# testing azure-functions moq
1个回答
0
投票

您没有写到您正在使用测试驱动开发(TDD),所以我假设您没有,但无论如何我都会将其带入讨论中,因为它也与本讨论相关。

TDD 的一个经常提到的好处是,它可以让设计问题比您注意到的更早地显现出来。这里的情况也是如此。测试只是突出了一个问题。

我不知道如何模拟

IMapper
(AutoMapper)、
IConfiguration
ILogger
,而不包含
AssetGovernance
AssetGovernance.Tests
的相关包依赖项以使接口可用。

简而言之,这就是问题所在。如果接口附带其实现,则它违反了依赖倒置原则(DIP),因为为了依赖于抽象,您还必须依赖于实现细节。

这就是您在这里遇到的问题。接口与其实现一起定义。如果您想遵循 DIP,您最多应该忽略依赖项定义的所有接口。相反,您可以定义自己的。根据 DIP,

“客户端[...]拥有抽象接口”

- APPP,罗伯特·C. 马丁,第 11 章

换句话说,客户端代码(在本例中为

AssetGovernace
)应该定义它所需的接口。相反,当它引入第三方接口时,就会破坏 DIP。

您可能会说使用这些第三方界面是“务实的”,并且您可以这样做。毕竟,没有法律规定您应该遵循 SOLID 原则。

但是,如果您选择这样做,并且想要使用 Moq 将它们替换为 Test Doubles,则还需要将这些依赖项添加到测试代码中。

© www.soinside.com 2019 - 2024. All rights reserved.