Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

102 lines
4.3 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Reflection;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.TestCommon
{
/// <summary>
/// MSTest assert class to make assertions about tests using <see cref="Task"/>.
/// </summary>
public class TaskAssert
{
private static int timeOutMs = System.Diagnostics.Debugger.IsAttached ? TimeoutConstant.DefaultTimeout : TimeoutConstant.DefaultTimeout * 10;
private static TaskAssert singleton = new TaskAssert();
public static TaskAssert Singleton { get { return singleton; } }
/// <summary>
/// Asserts the given task has been started. TAP guidelines are that all
/// <see cref="Task"/> objects returned from public API's have been started.
/// </summary>
/// <param name="task">The <see cref="Task"/> to test.</param>
public void IsStarted(Task task)
{
Assert.NotNull(task);
Assert.True(task.Status != TaskStatus.Created);
}
/// <summary>
/// Asserts the given task completes successfully. This method will block the
/// current thread waiting for the task, but will timeout if it does not complete.
/// </summary>
/// <param name="task">The <see cref="Task"/> to test.</param>
public void Succeeds(Task task)
{
IsStarted(task);
task.Wait(timeOutMs);
AggregateException aggregateException = task.Exception;
Exception innerException = aggregateException == null ? null : aggregateException.InnerException;
Assert.Null(innerException);
}
/// <summary>
/// Asserts the given task completes successfully and returns a result.
/// Use this overload for a generic <see cref="Task"/> whose generic parameter is not known at compile time.
/// This method will block the current thread waiting for the task, but will timeout if it does not complete.
/// </summary>
/// <param name="task">The <see cref="Task"/> to test.</param>
/// <returns>The result from that task.</returns>
public object SucceedsWithResult(Task task)
{
Succeeds(task);
Assert.True(task.GetType().IsGenericType);
Type[] genericArguments = task.GetType().GetGenericArguments();
Assert.Equal(1, genericArguments.Length);
PropertyInfo resultProperty = task.GetType().GetProperty("Result");
Assert.NotNull(resultProperty);
return resultProperty.GetValue(task, null);
}
/// <summary>
/// Asserts the given task completes successfully and returns a <typeparamref name="T"/> result.
/// This method will block the current thread waiting for the task, but will timeout if it does not complete.
/// </summary>
/// <typeparam name="T">The result of the <see cref="Task"/>.</typeparam>
/// <param name="task">The <see cref="Task"/> to test.</param>
/// <returns>The result from that task.</returns>
public T SucceedsWithResult<T>(Task<T> task)
{
Succeeds(task);
return task.Result;
}
/// <summary>
/// Asserts the given <see cref="Task"/> completes successfully and yields
/// the expected result.
/// </summary>
/// <param name="task">The <see cref="Task"/> to test.</param>
/// <param name="expectedObj">The expected result.</param>
public void ResultEquals(Task task, object expectedObj)
{
object actualObj = SucceedsWithResult(task);
Assert.Equal(expectedObj, actualObj);
}
/// <summary>
/// Asserts the given <see cref="Task"/> completes successfully and yields
/// the expected result.
/// </summary>
/// <typeparam name="T">The type the task will return.</typeparam>
/// <param name="task">The task to test.</param>
/// <param name="expectedObj">The expected result.</param>
public void ResultEquals<T>(Task<T> task, T expectedObj)
{
T actualObj = SucceedsWithResult<T>(task);
Assert.Equal(expectedObj, actualObj);
}
}
}