Я пытаюсь написать модульный тест, который может охватить кусок многопоточного кода 100% времени для покрытия кода.Код можно получить ТОЛЬКО в контексте многопоточного приложения, и он спроектирован так, чтобы его можно было запускать только один раз для каждого экземпляра объекта, чтобы минимизировать затраты времени блокировки.
В качестве упрощенного примера:
public class Example
{
private readonly object lockObject = new object();
private int? objectToInit = null;
public void EnsureObjectInit()
{
//To minimize hitting the lock code, the object is checked first.
if (!objectToInit.HasValue)
{
lock (lockObject)
{
//Then it is checked once more to ensure that it wasn't initiazlized
//before the lock was hit.
if (objectToInit.HasValue)
{
//This block can only be executed if a second thread is able to
//get to the lock before the first can initialize the object.
return;
}
objectToInit = 0;
}
}
}
}
Чтобы получить покрытие кода для попадания кода во второй оператор if, я пробовал код, подобный следующему:
[TestClass]
public class ExampleTest
{
[Test Method]
public void async MyTest()
{
Example example = new Example();
void runTask()
{
example.EnsureObjectInit();
}
//I've tried increasing the number of threads, but it doesn't make
//it hit the noted code any more consistently.
List<Task> tasks = new List<Task>(2);
tasks.Add(Task.Run(runTask));
tasks.Add(Task.Run(runTask));
await Task.WhenAll(tasks);
... perform extra validation ...
}
}
Но покрытие кода не достигает внутреннего блока if, по крайней мере, на 50%время.
Есть ли способ заставить тестируемый модулем код остановить первый поток перед инициализацией объекта, чтобы второй поток мог попасть в первый блок if?