2017-07-14 92 views
1

我想了解爲什麼下面的單元測試不執行回調。如果我修改代碼以便UpdateWorklowInstanceState方法只包含2個參數(Guid和IList),它就可以工作。但是,有一些有關3個參數的干擾。Moq回調不與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

你是什麼意思干擾,你收到什麼錯誤信息,期望的行爲與觀察到的行爲是什麼? –

+0

我的意思是干涉是回調似乎沒有得到執行。沒有錯誤信息。我期望看到「錯誤發生」消息,但會收到「元素更新」消息,這意味着回調沒有使用NotificationMessage填充resultMessages。 –

+0

你應該用上面的方法編輯你的問題。 –

回答

0

它不會在你的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以獲得更好的瞭解如何使用模擬框架。

0

請考慮在單元測試中的小地方更新。 添加嘲笑IWebApiBusinessObject對象之前:

List<NotificationMessage> messages = new List<NotificationMessage>(); 

此外,更新Callback

var mock = new Mock<IWebApiBusinessObject>(); 
      mock. 
      Setup(m => m.UpdateWorkflowInstanceState(It.IsNotNull<Guid>(), It.IsNotNull<WorkflowElementInstance>(),It.IsAny<List<NotificationMessage>>())). 
      Callback(() => 
       { 
        messages.Add(new NotificationMessage("error msg", MessageSeverity.Severe)); 
        messages.Add(new NotificationMessage("Ignore Message", MessageSeverity.Normal)); // this is optional... u can remove it if u want. 
       }); 

而需要更新的源代碼的方法UpdateWorkflowElement(WorkflowElementModel model)

UpdateWorkflowElement(WorkflowElementModel model, List<NotificationMessage> messages); 

考慮單元測試代碼改變主叫UpdateWorkflowElement

var result = controller.UpdateWorkflowElement(workflowElementModel, messages); 

如果我明白你的UpdateWorkflowInstanceState()方法正確,然後 您使用IWebApiBusinessObject調用UpdateWorkflowInstanceState(, ,)方法。 在單元測試期間執行UpdateWorkflowInstanceState(, ,)時,它在單元測試中觸發Callback,並在NotificationMessage列表中添加消息。

+0

我理解你的建議,但它是UpdateWorkflowInstanceState方法,它返回消息列表,而不是UpdateWorkflowElement。請注意,如果我修改UpdateWorkflowInstanceState以僅接受2個參數(Guid和IList ),則回調起作用。我也嘗試過使用WorkflowElementInstance和IList 獲取參數,它也可以工作。有關3個參數的事情正在產生問題。 –