如何在Azure持久函数中模拟对持久实体的调用?

时间:2020-04-06 19:46:36

标签: azure azure-functions azure-durable-functions

我正在使用MOQ来模拟持久实体,但是看到此错误:

扩展方法(此处为DurableContextExtensions.CallEntityAsync)可能 不能在设置/验证表达式中使用。

这是我的做法:

mockContext.Setup(e => e.CallEntityAsync<List<string>>(It.IsAny<EntityId>(), "EntityFunctionName"))
                .ReturnsAsync(new List<string>() {"one", "two", "three" });

有什么方法可以模拟对我的持久实体的调用?

1 个答案:

答案 0 :(得分:4)

从“持久功能2.3.0”开始,我们所有的扩展方法现在都直接烘焙到接口中,因此将Moq与所有这些方法及其重载一起使用应该明显更容易。

编辑:下面的上一个答案涵盖了为什么以前的扩展方法使这一难题变得如此。

因此,这是Moq与扩展方法一起使用的固有局限性。

不幸的是,与此同时,您将需要在IDurableOrchestrationContext上找到由扩展方法调用的核心方法,该方法提供了您正在使用的重载。

例如,在这种情况下,DurableContextExtension.CallEntityAsync(EntityId entityId, string operationName)正在调用IDurableOrchestrationContext.CallEntityAsync(EntityId entityId, string operationName, object operationInput),而null的值为operationInput。您可以通过查看source code来找到它。

这显然不是理想的模拟方法,因为如果不看我们的源代码,很难在编写测试时确定是否尝试模拟扩展方法。您可以使用Moq analyzer至少在编译时捕获这些错误,但是它仍然不会告诉您要模拟哪个方法签名来消除错误。

基于这个原因,我们建议完全放弃扩展方法,并将所有这些签名重载直接作为接口方法,以便您可以安全地模拟其中的任何一个。对于通过直接实现接口来编写测试的客户而言,这是一个重大更改,因此,我们试图将这一更改排除在补丁程序版本之外,并且仅在次要版本中提供明确的指导,以指导如何解决因这些更改而导致的问题。寻找此问题在扩展版本2.3.0中得到解决。