如何使用Task里面的单元测试void方法

时间:2014-05-23 11:21:08

标签: c# unit-testing task-parallel-library

我有一个图形方法CancelChanges()由ViewModel使用和调用。 我想测试这个方法,但我们内部有一个Task。 我们使用Task来不冻结UI。 我的测试方法需要等待此任务的结果来检查结果。

代码是:

public override void CancelChanges()
{
        Task.Run(
            async () =>
                {
                    this.SelectedWorkflow = null;
                    AsyncResult<IncidentTypeModel> asyncResult = await this.Dataprovider.GetIncidentTypeByIdAsync(this.Incident.Id);

                    Utils.GetDispatcher().Invoke(
                        () =>
                            {
                                if (asyncResult.IsError)
                                {
                                    WorkflowMessageBox.ShowException(
                                        MessageHelper.ManageException(asyncResult.Exception));
                                }
                                else
                                {
                                    this.Incident = asyncResult.Result;
                                    this.Refreshdesigner();
                                    this.HaveChanges = false;
                                }
                            });
                });
}

我的测试方法:

/// <summary>
///     A test for CancelChanges
/// </summary>
[TestMethod]
[TestCategory("ConfigTool")]
public void CancelChangesTest()
{
    string storexaml = this._target.Incident.WorkflowXamlString;
    this._target.Incident.WorkflowXamlString = "dsdfsdgfdsgdfgfd";

    this._target.CancelChanges();

    Assert.IsTrue(storexaml == this._target.Incident.WorkflowXamlString);
    Assert.IsFalse(this._target.HaveChanges);
}

我们如何让我的测试等待任务的结果?

感谢。

2 个答案:

答案 0 :(得分:9)

使CancelChanges方法返回Task,然后等待或在测试方法中设置延续。有些像

public override Task CancelChanges()
{
    return Task.Factory.StartNew(() =>
        {
            // Do stuff...
        });
}

注意从Task.RunTask.Factory.StartNew的更改。在这种情况下,这是启动任务的更好方法。然后在测试方法

[TestMethod]
[TestCategory("ConfigTool")]
public void CancelChangesTest()
{
    string storexaml = this._target.Incident.WorkflowXamlString;
    this._target.Incident.WorkflowXamlString = "dsdfsdgfdsgdfgfd";
    this._target.CancelChanges().ContinueWith(ant => 
        {
            Assert.IsTrue(storexaml == this._target.Incident.WorkflowXamlString);
            Assert.IsFalse(this._target.HaveChanges);
        });
}

您还可以将测试方法标记为async,并在测试方法中使用await来执行相同的操作。

我希望这会有所帮助。

答案 1 :(得分:1)

我会进一步重构,如果可能,请避免使用Task.Run。由于您所做的只是等待然后在UI线程上调用工作,我将执行以下操作:

public override Task CancelChanges()
{
     this.SelectedWorkflow = null;
     AsyncResult<IncidentTypeModel> asyncResult =       await    this.Dataprovider.GetIncidentTypeByIdAsync(this.Incident.Id);
     if (asyncResult.IsError)
     {          WorkflowMessageBox.ShowException(MessageHelper.ManageException(asyncResult.Exception));
     }        
    else
    {
         this.Incident = asyncResult.Result;
         this.Refreshdesigner();
         this.HaveChanges = false;
     }
   });
 });
}

测试方法:

[TestMethod]
[TestCategory("ConfigTool")]
public async Task CancelChangesTest()
{
  string storexaml =   this._target.Incident.WorkflowXamlString;
  this._target.Incident.WorkflowXamlString = "dsdfsdgfdsgdfgfd";

  var cancelChanges = await  this._target.CancelChanges();

  Assert.IsTrue(storexaml == this._target.Incident.WorkflowXamlString);
  Assert.IsFalse(this._target.HaveChanges);
}