MSTEST - асинхронный тест
Просто интересно, если кто-нибудь подумает так:
Это неправильный дизайн, чтобы иметь асинхронный вызов в TestInitialize, поскольку TestInitialize должен произойти до любого TestMethod.
Может ли это быть правильный подход, чтобы иметь асинхронный TestInitialize?
private int val = 0;
[TestInitialize]
public async Task TestMehod1()
{
var result = await LongRunningMethod();
val = 10;
}
[TestMethod]
public void TestMehod2()
{
Assert.AreEqual(10, val);
}
любая мысль?
Ответы
Ответ 1
Вероятно, самый чистый способ сделать это состоит в том, чтобы TestInitialize
запускал асинхронную операцию:
[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);
}
}
Ответ 2
То, что вы хотите сделать, - использовать .Result
или .Wait()
для синхронного блокирования метода TestInitialize
. Вы можете сделать следующее:
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);
}
Ответ 3
Просто создайте массив задач для различных вызовов инициализации (каждая возвращаемая задача), а затем используйте 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()
{
}
Ответ 4
Ваш код правильный!
Чтобы уточнить этот ответ 5 лет, через 2 месяца после первоначального вопроса. В то время наличие async [TestInitialize]
могло быть ошибкой компиляции, но в наши дни это не так.
Можно использовать async [TestInitialize]
, async [ClassInitialize] и async [TestMethod], просто используя await.
Использование async и await должным образом, вероятно, самый чистый способ сделать это. У меня есть что-то вроде следующего в моем коде, где мне нужно получить нашу структуру категорий, чтобы иметь возможность проверить, хорошо ли мои классы работают с имеющейся у нас структурой категорий.
private Category rootCategory;
[TestInitialize]
public async Task TestInitialize()
{
var loader = new CategoryLoader();
rootCategory = await loader.GetAllCategoriesAsync();
}
[TestInitialize]
запускается перед каждым [TestMethod]
, поэтому в зависимости от того, что я пытаюсь здесь протестировать, может быть лучше загрузить только один раз, а затем сделать все утверждения, чтобы не платить за время загрузки несколько раз. Но вы должны быть осторожны, чтобы тесты не влияли друг на друга, чтобы получить согласованные и правильные результаты.
Просто обратите внимание, что это больше не модульное тестирование, так как я тестирую интеграцию с внешним сервисом.