【问题标题】:In .NET what is a way to test an Async Lock, proving that reentrancy is prevented?在 .NET 中,有什么方法可以测试异步锁,证明可以防止重入?
【发布时间】:2015-10-31 07:55:39
【问题描述】:

假设我有一个这样的方法想要测试:

public async Task ConnectAsync()
{
    using (await _connectMutex.LockAsync())
    {
        await Task.Delay(1000);
    }
}

我对直接测试锁不感兴趣(我相信AsyncLock 的开发人员知道他在做什么)。相反,我想演示/证明的是,如果我同时使用 3 个线程来使用此方法,则总测试执行时间将 >= 3 秒。我的问题很简单:如何安排这样的测试?

【问题讨论】:

  • 为什么要测试互斥锁? _connectMutex 是什么?通常由该类型的开发人员来测试它,我只相信它可以正常工作,就像说“我如何测试string.Length”,真的你不应该这样做。
  • @RonBeyer 并非世界上的每个开发人员都是绝对可靠的。有时,除了你之外的人编写的代码中存在错误。
  • @Servy 100% 同意,如果这是从 GitHub 上提取的不包含任何单元测试的代码,那么一定要为它编写一个测试,但如果它是来自受信任组的已知框架(例如 MS,并且没有说它不是内置互斥锁),那么我不会浪费时间尝试测试它,除非您尝试重现错误。如果你想发布代码,你必须选择/选择战斗,这是我不会选择的,除非有什么理由让我这样做(错误)。
  • @RonBeyer 这不像是框架类型。这是第 3 方类型。 会相信它,但我又非常熟悉 Steven 的工作。对于其他可能没有足够理由相信 Steven 的人来说,为他的库编写一些测试是完全合理的。当然,值不值也要看项目;不同的项目对正确性的自信程度有不同的要求。当您为起搏器编写代码时,人们的生命实际上掌握在您手中,您可能会编写一些额外的测试用例。
  • @Servy 我错过了 OP 更新了我的第一个评论和最后一个评论之间的帖子,以包含关于这个第 3 方的信息(我最初认为它是内置的)。根据用例,是的,为此编写一个测试是合理的,我个人会分叉它并在它进入的任何集成项目之外编写专用测试。这样它就可以被推回。

标签: c# .net unit-testing async-await reentrancy


【解决方案1】:

如果您的异步锁具有这样的语义,即如果锁可用,则同步授予锁(这是一个合理的假设),那么您可以这样测试它:

[TestMethod]
public void PreventsReentrancy()
{
  var mutex = ...;
  var firstLock = mutex.LockAsync();
  var secondLock = mutex.LockAsync();

  Assert.IsTrue(firstLock.IsCompleted);
  Assert.IsFalse(secondLock.IsCompleted);
}

编辑更新的问题:

我想演示/证明的是,如果我同时使用 3 个线程执行此方法,则总测试执行时间将 >= 3 秒。我的问题很简单:如何安排这样的测试?

首先,我会仔细检查真的您想要测试的内容。由于这是我的AsyncLock,我可以说已经有单元测试验证了互斥并防止了重入锁。我真的,强烈避免对任何与时间相关的东西进行单元测试。

但是如果您实际上想要进行有时间要求的单元测试,我建议首先挂钩 Task.Delay 方法(例如,使用 Microsoft Fakes)并将其替换为使用Rx 的 IScheduler 而不是计时器。然后可以使用 Rx 的TestScheduler 来验证时序行为。

【讨论】:

    【解决方案2】:

    你不应该使用它周围的方法来测试锁。如果要测试锁直接测试锁:

    public async Task TestAsync()
    {
        using (await _connectMutex.LockAsync())
        using (await _connectMutex.LockAsync())
    }
    

    假设这是您的锁实现。如果它是外部的,则将其留给开发人员,否则您需要测试所有内容

    【讨论】:

      猜你喜欢
      • 2020-05-08
      • 2013-12-06
      • 2016-05-21
      • 2018-02-05
      • 1970-01-01
      • 2012-02-01
      • 1970-01-01
      • 2018-07-08
      • 2014-01-01
      相关资源
      最近更新 更多