Just wondering, if anyone thought like this:
This is incorrect design to have async call within TestInitialize, as TestInitialize has to happen before any TestMethod.
Can this be correct approach in any way to have async TestInitialize as well?
private int val = 0;
[TestInitialize]
public async Task TestMehod1()
{
var result = await LongRunningMethod();
val = 10;
}
[TestMethod]
public void TestMehod2()
{
Assert.AreEqual(10, val);
}
any thought?
Probably the cleanest way to do this is to have TestInitialize
start the asynchronous operation, as such:
[TestClass]
public class UnitTestAsync
{
private Task<int> val = null;
[TestInitialize]
public void TestInitializeMethod()
{
val = TestInitializeMethodAsync();
}
private async Task<int> TestInitializeMethodAsync()
{
return await LongRunningMethod();
}
private async Task<int> LongRunningMethod()
{
await Task.Delay(20);
return 10;
}
[TestMethod]
public async Task TestMehod2()
{
Assert.AreEqual(10, await val);
}
}
What you want to do is to use .Result
or .Wait()
to synchronously block the TestInitialize
decorated method. You can do the following:
private int val = 0;
[TestInitialize]
public void TestMehod1()
{
Task<object> result = await LongRunningMethod();
result.Wait();
val = 10;
}
[TestMethod]
public void TestMehod2()
{
Assert.AreEqual(10, val);
}
Just create an array of task for various initialization calls ( each return task) and then use Task.WaitAll()
[ClassInitialize()]
public static void Initialize(TestContext context)
{
List<Task> tasks = new List<Task>();
tasks.Add(InitializeMethod1());
tasks.Add(InitializeMethod2());
Task.WaitAll(tasks.ToArray());
}
public static async Task InitializeMethod1()
{
}
public static async Task InitializeMethod2()
{
}
Your code is correct!
To clarify this answer is 5 years, 2 months after the initial question. Back then having async [TestInitialize]
might have been a compile error, but these days it isn't.
It's possible to have async [TestInitialize]
, async [ClassInitialize]
and async [TestMethod]
just simply use await.
Using async and await properly is probably the cleanest way to do it. I have something like the following in my code where I need to get our category structure in order to be able to test if the my classes work well with the category structure that we have.
private Category rootCategory;
[TestInitialize]
public async Task TestInitialize()
{
var loader = new CategoryLoader();
rootCategory = await loader.GetAllCategoriesAsync();
}
[TestInitialize]
runs before every [TestMethod]
, so depending on what I'm trying to test here, it might be better to load only once and then make all the assertions, to not pay for the loading time multiple times. But you need to be careful so that the tests don't affect each other to get consistent and correct results.
Just a note that this is not a unit test anymore since I'm testing integration with external service.