c# - Moq 回调不适用于 3 参数方法

标签 c# unit-testing moq

我试图理解为什么以下单元测试不执行回调。如果我修改代码,使 UpdateWorklowInstanceState 方法仅包含 2 个参数(Guid 和 IList),则它可以工作。然而,有 3 个参数会产生干扰。

我所说的干扰是指回调似乎没有被执行。没有错误消息。我希望看到“发生错误”消息,但收到“元素已更新”消息,这意味着回调未使用 NotificationMessage 填充 resultMessages。

public void BusinessObjectReturnsErrorNotification_ReturnErrorMessage()
        {
            var workflowInstanceGuid = Guid.NewGuid();

            var workflowElementModel = new WorkflowElementModel
            {
                ElementName = "ValidName",
                WorkflowInstanceId = workflowInstanceGuid.ToString()
            };

            var workflowElementInstance = new WorkflowElementInstance
            {
                ElementName = workflowElementModel.ElementName,
                FullDescription = "Full Description",
                SummaryDescription = "Summary Description",
                RefTime = DateTime.Now,
                ElementType = "ElementType"
            };

            var mockWebApiBusinessObject = new Mock<IWebApiBusinessObject>();
            mockWebApiBusinessObject.Setup(m => m.UpdateWorkflowInstanceState(workflowInstanceGuid, workflowElementInstance, It.IsAny<List<NotificationMessage>>()))
                .Callback<Guid, WorkflowElementInstance, IList<NotificationMessage>>(
                    (workflowInstanceId, elementDetails, resultMessages) =>
                    {
                        resultMessages.Add(new NotificationMessage("An Error Occured!", MessageSeverity.Error));
                    });

            var controller = new WorkflowElementController(mockWebApiBusinessObject.Object);
            var result = controller.UpdateWorkflowElement(workflowElementModel);

            Assert.AreEqual("An Error Occured!", result.Content.ReadAsStringAsync().Result);
        }

测试方法:

[HttpPost]
    [ActionName("UpdateWorkflowElement")]
    public HttpResponseMessage UpdateWorkflowElement(WorkflowElementModel workflowElementModel)
    {
        if (!ModelState.IsValid || workflowElementModel == null)
        {
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }

        var response = new HttpResponseMessage(HttpStatusCode.OK);
        string responseMessage;

        if (workflowElementModel.RefTime == DateTime.MinValue)
        {
            workflowElementModel.RefTime = DateTime.UtcNow;
        }

        var resultMessages = new List<NotificationMessage>();
        var instanceId = new Guid();

        if (string.IsNullOrWhiteSpace(workflowElementModel.WorkflowInstanceId) ||
            string.IsNullOrWhiteSpace(workflowElementModel.ElementName))
        {
            responseMessage = "WorkflowInstanceId or ElementName are null or empty";
        }
        else if (!Guid.TryParse(workflowElementModel.WorkflowInstanceId, out instanceId))
        {
            responseMessage = "WorkflowInstanceId is not a valid Guid";
        }
        else
        {
            var element = new WorkflowElementInstance
            {
                ElementName = workflowElementModel.ElementName,
                RefTime = workflowElementModel.RefTime,
                SummaryDescription = workflowElementModel.SummaryDescription ?? "",
                FullDescription = workflowElementModel.FullDescription ?? ""
            };

            _webApiBusinessObject.UpdateWorkflowInstanceState(instanceId, element, resultMessages);

            responseMessage = "Element Updated";
        }

        if (NotificationMessage.HasErrors(resultMessages))
        {
            responseMessage = resultMessages.Find(m => m.Status == MessageSeverity.Error).Message;
        }

        response.Content = new StringContent(responseMessage);
        return response;
    }

最佳答案

它不适用于 3 个参数的情况,因为您正在混合表达式参数类型。

It.IsAny<List<NotificationMessage>>()

在设置中,与

相反
IList<NotificationMessage>

在回调参数中。

这意味着设置表达式参数与回调表达式参数不匹配,因此不会调用回调。

坚持使用一种类型,所以要么选择 List<NotificationMessage>对于两者

您还在测试的方法中创建参数的新实例,该实例与设置中使用的实例不同。这就是回调不起作用的原因。为了证明这一点。使用It.IsAny<>()对于所有参数,它应该可以工作

mockWebApiBusinessObject
    .Setup(m => m.UpdateWorkflowInstanceState(It.IsAny<Guid>(), It.IsAny<WorkflowElementInstance>(), It.IsAny<List<NotificationMessage>>()))
    .Callback<Guid, WorkflowElementInstance, List<NotificationMessage>>(
                (workflowInstanceId, elementDetails, resultMessages) =>
                {
                    resultMessages.Add(new NotificationMessage("An Error Occured!", MessageSeverity.Error));
                });

或更通用的界面

mockWebApiBusinessObject
    .Setup(m => m.UpdateWorkflowInstanceState(It.IsAny<Guid>(), It.IsAny<WorkflowElementInstance>(), It.IsAny<IList<NotificationMessage>>()))
    .Callback<Guid, WorkflowElementInstance, IList<NotificationMessage>>(
                (workflowInstanceId, elementDetails, resultMessages) =>
                {
                    resultMessages.Add(new NotificationMessage("An Error Occured!", MessageSeverity.Error));
                });

您还应该花一些时间查看 Moq Quickstart更好地了解如何使用模拟框架。

关于c# - Moq 回调不适用于 3 参数方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45107856/

相关文章:

c# - 如何使用 LINQ 查询嵌入的 XML 文件?

python - 如何将我的数据写入 json 文件?

java - 模拟 swagger 自动生成的 api 类

mocking - 为什么接口(interface)首选模拟?

c# - 检查 PC 是否连接在 LAN 上

c# - 从 WebMethod 返回对象 (AJAX ASP.net)

c# - C# 中的颜色一致性向量

unit-testing - Angular 2 Jasmine 无法绑定(bind)到 'routerLink',因为它不是 'a' 的已知属性

c# - 如何使用 Moq 来满足单元测试的 MEF 导入依赖?

c# - 使用最小起订量部分模拟类