public class LockTest
{
private IDatabase _database;
private readonly Random _random = new Random();
private int _num = 0; [SetUp]
public void SetUp()
{
_num = 0; //信号量,同时访问的线程1
var slim = new SemaphoreSlim(1, 1); //mock redis的接口
_database = Substitute.For<IDatabase>(); //mock LockTake 同时只有一个线程可以拿到锁
//slim.WaitAsync 参数为0时标识直接返回是否拿到锁,不会类似lock阻塞直至其他人释放
//这里主要mock redis的场景,拿不到要使用循环重复尝试拿锁,因此传0
//普通异步锁场景根据需求选择等待时间,使用等待时间理论上使用响应时间应比自己写循环简单且有更好的性能
_database.LockTakeAsync(Arg.Any<RedisKey>(), Arg.Any<RedisValue>(), Arg.Any<TimeSpan>())
.Returns(async call => await slim.WaitAsync(call.ArgAt<TimeSpan>(2))); //mock LockRelease 释放锁
_database.LockReleaseAsync(Arg.Any<RedisKey>(), Arg.Any<RedisValue>()).Returns(call =>
{
slim.Release();
return true;
});
} /// <summary>
/// 使用锁的版本,_num值会按预期加至5
/// </summary>
/// <returns></returns>
[Test]
public async Task WithLockTest()
{
var tasks = Enumerable.Range(1, 5).Select(c => LockTestTaskInner("1", "1", TimeSpan.FromSeconds(0)));
await Task.WhenAll(tasks);
Assert.AreEqual(_num, 5);
} /// <summary>
/// 无锁版本,_num值会配其他线程覆盖
/// </summary>
/// <returns></returns>
[Test]
public async Task WithoutLockTestTask()
{
var tasks = Enumerable.Range(1, 5).Select(async c =>
{
var tmp = _num;
//模拟覆盖写
await Task.Delay(_random.Next(5));
_num = tmp + 1;
});
await Task.WhenAll(tasks);
Console.WriteLine(_num);
Assert.AreNotEqual(_num, 5);
} private async Task LockTestTaskInner(string key, string value, TimeSpan expiry)
{
var reTryGetLock = true;
while (reTryGetLock)
{
var taskLockSuccess = await _database.LockTakeAsync(key, value, expiry);
if (taskLockSuccess)
{
reTryGetLock = false;
try
{
var tmp = _num;
//模拟覆盖写
await Task.Delay(_random.Next(5));
_num = tmp + 1;
}
finally
{
await _database.LockReleaseAsync(key, value);
}
}
else
{
//证明LockTakeAsync不会阻塞
//Console.WriteLine("retry");
await Task.Delay(_random.Next(10));
}
} }

单元测试NUnit,mock组件NSubstitute,信号量SemaphoreSlim,异步lock等例子的更多相关文章

  1. Spring Boot单元测试(Mock)

    Spring Boot单元测试(Mock) Java个人学习心得 2017-08-12 16:07 Mock 单元测试的重要性就不多说了,我这边的工程一般都是Spring Boot+Mybatis(详 ...

  2. MVC文件上传04-使用客户端jQuery-File-Upload插件和服务端Backload组件实现多文件异步上传

    本篇使用客户端jQuery-File-Upload插件和服务端Badkload组件实现多文件异步上传.MVC文件上传相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证类型和大小  ...

  3. Java单元测试(Junit+Mock+代码覆盖率)---------转

    Java单元测试(Junit+Mock+代码覆盖率) 原文见此处 单元测试是编写测试代码,用来检测特定的.明确的.细颗粒的功能.单元测试并不一定保证程序功能是正确的,更不保证整体业务是准备的. 单元测 ...

  4. c# 异步调用简单例子(转载)

    首先来看一个简单的例子: 小明在烧水,等水烧开以后,将开水灌入热水瓶,然后开始整理家务 小文在烧水,在烧水的过程中整理家务,等水烧开以后,放下手中的家务活,将开水灌入热水瓶,然后继续整理家务 这也是日 ...

  5. 并发教程--JAVA5中 计数信号量(Counting Semaphore)例子

    并发教程--JAVA5中 计数信号量(COUNTING SEMAPHORE)例子 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java中的计数信息量(C ...

  6. NUnit+mock+moq单元测试

    [TestFixture] public class InstantBatchBuyTest { private string _mallAbc; private string _itemCode; ...

  7. 企业应用架构研究系列二十六:信号量SemaphoreSlim与Semaphore

    在进行多线程程序的开发和设计的过程中,不可避免的需要引入semaphore信号量这个组件,这是.net框架提供的一个对多线程计数互斥的方案,就是允许指定的线程个数访问特定的资源而增加的 一个" ...

  8. Python3的单元测试模块Mock与性能测试模块CProfile

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_92 我们知道写完了代码需要自己跑一跑进行测试,一个写好的程序如果连测试都没有就上到生产环境是不敢想象的,这么做的人不是太自信就是太 ...

  9. Python单元测试和Mock测试

    单元测试 测试可以保证你的代码在一系列给定条件下正常工作 测试允许人们确保对代码的改动不会破坏现有的功能 测试迫使人们在不寻常条件的情况下思考代码,这可能会揭示出逻辑错误 良好的测试要求模块化,解耦代 ...

随机推荐

  1. 洛谷2805 [NOI2009]植物大战僵尸 (拓扑排序+最小割)

    坚决抵制长题面的题目! 首先观察到这个题目中,我们会发现,我们对于原图中的保护关系(一个点右边的点对于这个点也算是保护) 相当于一种依赖. 那么不难看出这个题实际上是一个最大权闭合子图模型. 我们直接 ...

  2. 洛谷4400 BlueMary的旅行(分层图+最大流)

    qwq 首先,我们观察到题目中提到的每天只能乘坐一次航班的限制,很容易想到建分层图,也就是通过枚举天数,然后每天加入一层新的点. (然而我一开始想的却是erf) 考虑从小到大枚举天数,然后每次新建一层 ...

  3. 试题 算法训练 最大最小公倍数 java题解

    资源限制 时间限制:1.0s   内存限制:256.0MB 问题描述 已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少. 输入格式 输入一个正整数N. 输出格式 输出一个整数 ...

  4. FastAPI 学习之路(六)查询参数,字符串的校验

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  5. 请问:c语言中d=1/3*3.0;与d=1.0/3*3;d=?有什么区别

    请问:c语言中d=1/33.0;与d=1.0/33;d=?有什么区别 d=1/33.0; 这时d=0,d=(1/3)3.0,这里1是整形,1/3也是整形,等于0,所以03.0=0 d=1.0/33; ...

  6. UltraSoft - Beta - Scrum Meeting 6

    Date: May 22n'd, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 修复了DDL日程自动发邮件被服务器"吞掉"的bug后端增加了 ...

  7. 基于自定义Validator来验证枚举类型

    基于自定义Validator来验证枚举类型 一.背景 二.技术要点 三.实现一个自定义枚举校验. 1.需求. 2.实现步骤 1.自定义一个 Sex 枚举. 2.自定义一个 Enum 注解 3.编写具体 ...

  8. TCP/IP参考模型(应用层、传输层、网际层、网络接口层)、五层参考模型(应用层、传输层、网络层、数据链路层、物理层)、OSI与TCP/IP参考模型比较

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/104597450 学习课程:<2019王道考研计算机网络> 学习目的 ...

  9. 彻底搞通TCP滑动窗口

    在我们当初学习网络编程的时候,都接触过TCP,在TCP中,对于数据传输有各种策略,比如滑动窗口.拥塞窗口机制,又比如慢启动.快速恢复.拥塞避免等.通过本文,我们将了解滑动窗口在TCP中是如何使用的. ...

  10. c++中virtual 虚函数

    转载: https://www.cnblogs.com/weiyouqing/p/7544988.html 在面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念. ...