在 .NET 中,有什么方法可以测试 Async Lock,以证明重入已被阻止?
In .NET what is a way to test an Async Lock, proving that reentrancy is prevented?
假设我有一个想要测试的方法:
public async Task ConnectAsync()
{
using (await _connectMutex.LockAsync())
{
await Task.Delay(1000);
}
}
我对直接测试锁不感兴趣(我相信 AsyncLock 的开发者知道他在做什么)。相反,我想要 demonstrate/prove 的是,如果我同时使用 3 个线程调用此方法,则总测试执行时间将 >= 3 秒。我的问题很简单:如何安排这样的测试?
您不应该使用锁周围的方法来测试锁。如果要测试锁直接测试锁:
public async Task TestAsync()
{
using (await _connectMutex.LockAsync())
using (await _connectMutex.LockAsync())
}
假设这是您的锁定实现。如果它是外部的,则将其留给开发人员,否则您将需要测试 everything.
如果您的异步锁具有同步授予锁(如果可用)的语义(这是一个合理的假设),那么您可以这样测试它:
[TestMethod]
public void PreventsReentrancy()
{
var mutex = ...;
var firstLock = mutex.LockAsync();
var secondLock = mutex.LockAsync();
Assert.IsTrue(firstLock.IsCompleted);
Assert.IsFalse(secondLock.IsCompleted);
}
编辑更新问题:
what I wanted to demonstrate/prove was that if I hit this method with 3 threads simultaneously, that the total test execution time will be >= 3 seconds. My question is simply: how would one arrange such a test?
首先,我会仔细检查确实您想要测试的内容。由于这是我的AsyncLock
,我可以说已经有单元测试验证互斥和防止可重入锁。我真的非常强烈地避免对任何与时间相关的内容进行单元测试。
但是如果你实际上想要做一个有时间要求的单元测试,我建议首先挂钩 Task.Delay
方法(例如,使用 Microsoft Fakes)和将其替换为使用 Rx 的 IScheduler
而不是计时器的实现。然后你可以使用 Rx 的 TestScheduler
来验证时序行为。
假设我有一个想要测试的方法:
public async Task ConnectAsync()
{
using (await _connectMutex.LockAsync())
{
await Task.Delay(1000);
}
}
我对直接测试锁不感兴趣(我相信 AsyncLock 的开发者知道他在做什么)。相反,我想要 demonstrate/prove 的是,如果我同时使用 3 个线程调用此方法,则总测试执行时间将 >= 3 秒。我的问题很简单:如何安排这样的测试?
您不应该使用锁周围的方法来测试锁。如果要测试锁直接测试锁:
public async Task TestAsync()
{
using (await _connectMutex.LockAsync())
using (await _connectMutex.LockAsync())
}
假设这是您的锁定实现。如果它是外部的,则将其留给开发人员,否则您将需要测试 everything.
如果您的异步锁具有同步授予锁(如果可用)的语义(这是一个合理的假设),那么您可以这样测试它:
[TestMethod]
public void PreventsReentrancy()
{
var mutex = ...;
var firstLock = mutex.LockAsync();
var secondLock = mutex.LockAsync();
Assert.IsTrue(firstLock.IsCompleted);
Assert.IsFalse(secondLock.IsCompleted);
}
编辑更新问题:
what I wanted to demonstrate/prove was that if I hit this method with 3 threads simultaneously, that the total test execution time will be >= 3 seconds. My question is simply: how would one arrange such a test?
首先,我会仔细检查确实您想要测试的内容。由于这是我的AsyncLock
,我可以说已经有单元测试验证互斥和防止可重入锁。我真的非常强烈地避免对任何与时间相关的内容进行单元测试。
但是如果你实际上想要做一个有时间要求的单元测试,我建议首先挂钩 Task.Delay
方法(例如,使用 Microsoft Fakes)和将其替换为使用 Rx 的 IScheduler
而不是计时器的实现。然后你可以使用 Rx 的 TestScheduler
来验证时序行为。