如何测试Job类执行期间锁的有效性?求设计优化建议
Job类锁机制的测试与设计优化疑问
现有Job类核心实现
为确保Job仅执行一次,我给Job类引入了自定义Locking机制,核心方法StartAsync代码如下:
public async Task StartAsync(CancellationToken cancellationToken) { if (this.@lock.IsLocked()) { return; } this.@lock.Lock(); await this.ExecuteAsync(new JobExecutionContext(cancellationToken)) .ConfigureAwait(false); this.@lock.Unlock(); }
已编写的测试用例
我遵循测试外部可观测行为而非实现细节的原则,使用AutoFixture编写了以下测试(已省略样板代码):
[Theory(DisplayName = "Starting a `Job` (when the lock is locked), does NOT execute it.")] [AutoDomainData] public async Task StartingWithLockedLockDoesLockNotExecuteIt([Frozen] Mock<ILock> lockMock, [Frozen] Mock<Job> jobMock) { // VALIDATION. ILock @lock = lockMock?.Object ?? throw new ArgumentNullException(nameof(lockMock)); Job job = jobMock?.Object ?? throw new ArgumentNullException(nameof(jobMock)); // MOCK SETUP. _ = lockMock.Setup(x => x.IsLocked()) .Returns(true); // ACT. await job.StartAsync(new CancellationToken()) .ConfigureAwait(false); // ASSERT. jobMock.Verify(job => job.ExecuteAsync(It.IsAny<IExecutionContext>()), Times.Never); } [Theory(DisplayName = "Starting a `Job` (when the lock is NOT locked), does lock the lock.")] [AutoDomainData] public async Task StartingWithNotLockedLockDoesExecuteIt([Frozen] Mock<ILock> lockMock, [Frozen] Mock<Job> jobMock) { // VALIDATION. ILock @lock = lockMock?.Object ?? throw new ArgumentNullException(nameof(lockMock)); Job job = jobMock?.Object ?? throw new ArgumentNullException(nameof(jobMock)); // MOCK SETUP. _ = lockMock.Setup(x => x.IsLocked()) .Returns(false); // ACT. await job.StartAsync(new CancellationToken()) .ConfigureAwait(false); // ASSERT. jobMock.Verify(job => job.ExecuteAsync(It.IsAny<IExecutionContext>()), Times.Once); }
已覆盖的测试场景
- 当锁处于锁定状态时,Job不会执行
- 当锁未锁定时,Job会执行
待解决的问题
目前缺少一个关键测试场景:确保Job执行期间,锁始终处于激活状态。同时我感觉现有设计可能存在优化空间,但不确定具体方向,希望得到以下帮助:
- 如何正确测试"Job执行期间锁始终激活"这个场景?
- 针对当前的锁机制设计,有哪些优化建议?
内容的提问来源于stack exchange,提问作者Complexity
相关产品推荐
相关产品推荐

