在我的一个NSubstitute单元测试中,我有一个目标类。
public void _UpdateChecklistStatus(object checklistViewModel)
{
OnCompletion<List<object>> updateChecklistStatusCallback = (result, ex) =>
{
if (result != null && result[0] != null && result[0] is bool)
{
Dispatcher.BeginInvoke(() =>
{
if (updateResult == false)
{
//some code to execute
}
});
}
m_ObjectManager.UpdateDataAsync(
new ChecklistDataModel(),
OperationType.SaveSingle,
new CacheSettings(),
updateChecklistStatusCallback,
updateChecklistStatuskParam,
Constants.PROFILE_UPDATE_CHECKLIST_STATUS);
};
}
我已经模拟了通过m_ObjectManager
调用(异步)WCF服务的对象UpdateDataAsync
,并使用有效结果回调回调updateChecklistStatusCallback
,该结果也被模拟。
现在问题是在模拟m_ObjectManager.UpdateDataAsync
之后,我将回调转换为updateChecklistStatusCallback
,但Dispatcher.BeginInvoke
中的代码永远不会被执行。
Dispatcher
位于System.Windows.Threading
。
我在Dispatcher.BegingInvoke
区块内的多个位置放置了断点,但没有一个被击中,单元测试成功完成。
有人可以帮我解决一下该怎么办?有没有办法嘲笑它或其他东西?
热切期待着回应!
谢谢,
要获得更清晰的信息,请粘贴实际代码: [测试方法] public void TestUpdatePriorityCommand() {
var res = new Dictionary<string, byte[]>();
res.Add("Test", (new byte[] { 100, 150, 170, 200 }));
var lstUpdateResObj = new List<object> { res };
_target.StartDateTime = new DateTime(2014, 02, 20);
_objManager.UpdateDataAsync(Arg.Any<ActivityModel>(), Arg.Is(OperationType.SaveSingle), Arg.Any<CacheSettings>(), Arg.InvokeDelegate<OnCompletion<List<object>>>(lstUpdateResObj, null), Arg.Any<ActivityUpdateParameters>(), Arg.Is(Constants.PROFILE_UPDATE_ACTIVITY_PRIORITY));
_target.UpdatePriorityCommand.Execute("High");
try
{
_objManager.ReceivedWithAnyArgs().UpdateDataAsync(Arg.Any<ActivityModel>(), Arg.Is(OperationType.SaveSingle), Arg.Any<CacheSettings>(), Arg.InvokeDelegate<OnCompletion<List<object>>>(lstUpdateResObj, null), Arg.Any<ActivityUpdateParameters>(), Arg.Is(Constants.PROFILE_UPDATE_ACTIVITY_PRIORITY));
}
catch (AmbiguousArgumentsException)
{
//throw;
}
}
执行测试后执行的方法:
private void _UpdateActivityPriority(object parameter)
{
string oldPriority = m_Activity.Priority;
if (IsSelected && !IsActivitySelectionEnabled)
{
MessageBoxResult msgBoxResult = MessageBox.Show(Utility.GetStringFromResource("ActivityListContainerViewModel_Edit_Launched_TaskAttributes"), Utility.GetStringFromResource("TasklistTitle"), MessageBoxButton.OKCancel);
if (msgBoxResult == MessageBoxResult.OK)
{
//List<ActivityViewModel> lstActivityViewModel = new List<ActivityViewModel>() { this };
//_UpdateSelectionList(lstActivityViewModel);
//_LaunchActivityInSequence(lstActivityViewModel);
HandleActivityNameClick.Execute(this);
}
_RefreshPriorityBasedUI();
return;
}
//Check if reminder time is greater than the due time for the activity
if (parameter != null && !string.IsNullOrEmpty(parameter.ToString()))
{
IDictionary<string, byte[]> updateRes;
ActivityUpdateParameters parameters = new ActivityUpdateParameters
{
ActivityInstanceSer = ActivityInstanceSer,
Priority = parameter.ToString(),
UserResourceSer = m_ActivityListContext.LoggedInUser.SerialNo,
Timestamp = m_Activity.Timestamp
};
OnCompletion<List<object>> myCallback = (result, ex) =>
{
if (ex != null)
{
//Reset to old priority
m_Activity.Priority = oldPriority;
IsReminderUpdateRequired = false;
Dispatcher.BeginInvoke(new Action(() => Utility.HandleException(ex, "TasklistTitle", "_UpdateActivityPriority()", "ActivityViewModel", "UpdateActivityPriority", true, "Err_ActivityPriorityUpdate", true)));
}
else
{
updateRes = (Dictionary<string, byte[]>)result[0];
Dispatcher.BeginInvoke(new Action(() =>
{
if (updateRes == null)
{
Utility.ShowMessage(Utility.GetStringFromResource("Err_ActivityPriorityUpdate"));
//Reset to old priority
m_Activity.Priority = oldPriority;
IsReminderUpdateRequired = false;
}
else
{
m_Activity.Priority = parameter.ToString();
ActivityData.Timestamp = new Dictionary<string, byte[]>(updateRes);
}
_RefreshPriorityBasedUI();
})
);
}
//Refresh UI based on the priority updates
IsUpdatePriorityInProgress = m_ActivityListContext.IsWaitingForCallback = false;
};
m_ObjectManager.SecurityToken = Utility.Instance.SecurityToken;
m_ObjectManager.ClientID = CLIENT_ID;
try
{
IsUpdatePriorityInProgress = m_ActivityListContext.IsWaitingForCallback = true;
m_ObjectManager.UpdateDataAsync(new ActivityModel(), OperationType.SaveSingle, new CacheSettings(), myCallback, parameters, Constants.PROFILE_UPDATE_ACTIVITY_PRIORITY);
}
catch (Exception ex)
{
IsUpdatePriorityInProgress = m_ActivityListContext.IsWaitingForCallback = false;
Utility.HandleException(ex, "TasklistTitle", "_UpdateActivityPriority()", "ActivityViewModel", "UpdateActivityPriority", false, "Err_ActivityPriorityUpdate", true);
}
}
“OnCompletion”是我们自定义的“Action”回调函数,它是由于模拟而调用的。 但是“Dispatcher.BeginInvoke(new Action(()=&gt;”中的代码从未受到重创。
为简单起见,这里的伪代码更容易理解问题:
//Unit test Class
[TestMethod]
public void TestCommand()
{
//callback mock here
var parameter;
//target is the object of the class which is to be tested
//Command of the target executed here
target.TestCommand.Execute(parameter);
}
//This is a method in the target class
//Called as a result of command execution in the test method as above
private void calledMethod(object parameter)
{
//ex is the exception that may be thrown by a service call
//"OnCompletion" is our custom delegate of type "Action"
OnCompletion<List<object>> myCallback = (result, ex) =>
{
if(ex==null)
{
Dispatcher.BeginInvoke(new Action(() =>
{
//some code here
//Issue: execution never comes here
})
}
}
//WCF Service asynchronous Call
//When the call completes, it calls the delegate "mycallback"
}
希望这次非常清楚。问题是回调委托“mycallback”被击中但“dispatcher.begininvoke”中的代码块从未执行。