Предполагая, что вы получаете доступ к реальной БД, вы попадаете в область интеграционных тестов. Самый простой способ - получить доступ к ресурсу из нескольких потоков. Например:
[Test]
public void SimpleStressTest()
{
bool wasExceptionThrown = false;
var threads = new Thread[100];
for(int i = 0; i < 100; i++)
{
threads[i] =
new Thread(new ThreadStart((Action)(() =>
{
try
{
AccessDB();
}
catch(Exception)
{
wasExceptionThrown = true;
}
})));
}
for(int i = 0; i < 100; i++)
{
threads[i].Start();
}
for(int i = 0; i < 100; i++)
{
threads[i].Join();
}
Assert.That(wasExceptionThrown, Is.False);
}
Этот тест не является детерминированным, так как вы не можете контролировать поток потоков. Если вы хотите убедиться, например, что 100 соединений могут быть открыты одновременно, вы можете поместить ловушку в логику AccessDB()
, которая заставит его ждать, пока он не закроет соединение с БД. *
Например, вместо предыдущего действия потока:
try
{
AccessDB(sychObject);
}
catch(Exception)
{
wasExceptionThrown = true;
}
После запуска всех потоков убедитесь, что у вас есть 100 потоков, ожидающих на sychObject
, и только затем отпустите его и присоединитесь к потокам. То же самое может быть достигнуто путем создания логики CloseConnection()
(например) virtual и написания теста для класса наследования, ожидающего в CloseConnection()
. Например:
public class DataBase
{
public void AccessDB()
{
// Do logic here before closing connection
CloseConnection();
}
protected virtual void CloseConnection()
{
// Real Logic to close connection
}
}
public class FakeDataBase : DataBase
{
ManualResetEvent sychObject;
public FakeDataBase(ManualResetEvent sychObject)
{
this.sychObject = sychObject;
}
override protected void CloseConnection()
{
sychObject.WaitOne();
base.CloseConnection();
}
}