作息时间规划
我不聪明,但愿意用努力和汗水,搏一条康庄大道。鉴于本人工作与专业基本不相关,所以计划至少学习 1050 小时。现在是 2 月 23 日,按复习到 9 月 31 日算,每天需要保证 5 小时的学习时长。
先积跬步,再至千里
已经是 2022 年了,本人自从 2019 年基础考过后,由于工作时间关系,一直没有报考专业考试。2020 年正值疫情爆发,本应是准备考试的好时机,但是恰巧公司 BIM 研发战略转向,开始开发基于网页的 BIM 应用。由于本人在这方面完全是一个新手,不得不放弃考试,学习网页开发知识。而 2021 年由于职称评聘需要写论文、新房交付、并要准备结婚,考试又这样被搁置了一年。
此时,春风渐暖,我寻思着,今年必须要发奋图强一次了,为至千里,先得积跬步。
Mongoose 中特殊类型的等价字符串表达形式
后端开放了一个通用的聚合查询,传入聚合语句即可获取结果,但是一些特殊类型无法通过
body
传到后端,比如
ObjectId
,Regexp
等。本文对这些特殊类型的等价表达方式进行了总结,以飨读者。
利用 HttpClient 进行网络请求并获取进度信息
.NET 下主要有三种方式可以进行网络请求相关操作,它们分别是
HttpWebRequest
,WebClient
和
HttpClient
。这三者的关系是不断递进发展的,所以一般使用
HttpClient
来进行网络请求。
本文主要讲述 HttpClient
的使用方法和进度获取。
Minio-js的正确安装与使用
本文主要介绍 minio-js
的正确安装与使用。在网上搜了好久,都没有找到一个能正常运行
minio-js
的使用教程,包括官网。所以本文对此进行总结。
Kodbox中用Minio当存储时上传大文件提示上传失败
本人使用 kobox 搭建了一个私有网盘,用 minio 搭建了一个对象存储作为 kodbox 的存储,但是最近在 kodbox 中上传稍大点的文件(大于 100K 左右)时,就提示上传失败,又很神奇的是,在 minio 却发现该文件已经成功上传了。
正文
上述问题困扰了我两天,然后偶然看到一个答案,顺利解决了。
I think the problem is caused by the proxy converting HEAD requests to GET requests.
I ran into this problem when using nginx as a reverse proxy and solved it by adding the following configuration:
proxy_cache_convert_head off;
所以,解决方法就是在 nginx 配置中添加:
1 | proxy_cache_convert_head off; |
后记
官方关于 minio 中反向代理的配置不全,导致怎么配置都有问题。这两天觉都没睡好,唉,坑是真的多呀,心累,不折腾了~
参考
.NET Core 单元测试从零基础到项目应用
本文讲述了如何在 .NET Core 的项目中从零开始搭建单元测试,然后达到项目应用的程度。通过本文,你可以 get 以下知识:
- .NET 中现有单元测试框架有哪些
- 为什么选择 MSTest 框架
- 如何创建一个单元测试
- 怎么运行单元测试
框架选型
我们在使用一种技术时,往往需要对现有技术调研,通过比较最终确定使用哪个。.NET 官方推荐的单元测试有 3 种:xUnit、NUnit、MSTest。
除了标注测试类和方法的特性用的不一样之外,它们是非常相似的。而 MSTest 与 VisualStudio 集成度更高,所以本人建议使用 MSTest。
StackOverflow 看到一条我很赞同的看法:
其实不用顾虑那么多,随便选择吧,MSTest 对 VS 的集成是最好的,而且也很容易上手,如果哪一天碰到它所无法解决的事情,切换到其他框架也非常简单,仅仅只是Nuget下个包,换下特性而已。
添加单元测试
在 VS 中,选中方法名,右键 -> 创建单元测试,点击确定。
通过上述步骤,VS 会自动创建一个单元测试项目,在该项目里面自动生成单元测试内容。
1 | // 标记测试类 |
编写测试案例
依赖注入怎么测试
ASP.NET Core 支持依赖关系注入 (DI) 软件设计模式,并且默认注入了很多服务,具体可以参考 官方文档, 相信只要使用过依赖注入框架的同学,都会对此有不同深入的理解,在此无需赘言。
然而,在引入 IOC 框架之后,对于之前常规的对于类的依赖(new Class)变成通过构造函数对于接口的依赖(ASP.NET CORE 默认注入方式),这本身更加符合依赖倒置原则,但是对于单元测试来说确会带来另一个问题:
由于层层依赖,导致在某个类的方法进行测试的时候,需要构造一大堆该类依赖的接口的实现,非常麻烦。
这个时候,我们脑子里会下意识想一个问题:为什么常用的 .Net 单元测试框架不支持依赖注入?
于是笔者带着这个问题在查阅了一些关于在单元测试中支持依赖注入的讨论Github Issue,以及其他的相关文档,突然明白一个之前一直忽视但实际却非常重要的问题:
在对于一个方法的单元测试中,我们应该关注的是这个方法内部的逻辑测试,而这个方法内部对于外部的依赖,则不在这个单元测试关注的范围内
换言之,单元测试永远都只关注需要测试的方法内部的逻辑实现,至于外部依赖方法的测试,则应该放在另一个专门针对这个方法的单元测试用例中。
弄清楚这个问题,我们才能更加理解另一个单元测试不可缺少的框架——Mock框架。在我们写的测试中,应该忽略外部依赖具体的实现,而是通过模拟该接口方法来显示的指定返回值,从而降低该返回值对于当前单元测试结果的影响,而 Mock 框架(例如最常用的Moq),刚好可以满足我们对于接口的模拟需求。
相信有同学跟我有同样的疑惑,并且当我尝试在 ASP.NET Core 单元测试中的一切外部依赖通过 Mock 的方式进行编写的时候,遇到了一些问题,下文会将这些问题一一道来,希望对有同样疑惑的同学有所帮助。
Mock 框架选择
在 .NET 中有几种 mock 框架可供选择,比如 NMock、PhinoMocks、FakeItEasy和Moq。尽管Moq相对较新,但是它非常易用。不需要像传统的 Record/Replay。并且使用 Moq 在 VS 中可以得到智能提示。学习成本也不高。
所以选择 Moq 作为 Mock 数据框架。Moq 有一个自动 Mock 库 Moq.AutoMock,建议安装该库。
Moq 基本使用
1 | var mock = new Mock<ILoveThisLibrary>(); |
上面的方式可以简化成:
1 | ILoveThisLibrary lovable = Mock.Of<ILoveThisLibrary>(l => |
简而言之,Mock 数据的使用步骤可总结如下:
- 新建一个 Mock 实例
mock
- 通过
mock
设置方法的返回值 - 通过
mock.Object
获取 Mock 的对象来传递给目标方法使用
Moq.AutoMock 使用
基本使用方法
1 | var mocker = new AutoMocker(); |
注入现有实例
1 | var mocker = new AutoMocker(); |
结语
CI/CD 流程中应该包含单元测试
例如在编写 Repository 层进行单元测试时,经常有同学会编写依赖于数据库数据的单元测试,这样并不利于随时随地的进行单元测试检查。
如果将该流程放在 CI/CD 中,在代码的发布过程中通过单元测试可以检查代码逻辑的正确性,同时依赖于数据库的单元测试将不会通过(通常情况下,生产环境和开发环境隔离),变相迫使开发小伙伴通过 mock 方式模拟数据库返回结果。
这个原则同样适用于不能依赖三方API编写单元测试。
CI/CD 是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。CI/CD 的核心概念是持续集成、持续交付和持续部署。作为一个面向开发和运营团队的解决方案,CI/CD 主要针对在集成新代码时所引发的问题(亦称:"集成地狱")。
单元测试覆盖率
通常很多开发 Leader 都会要求开发团队编写单元测试,但是很少检查单元测试的质量,即单元测试最重要的指标——单元测试代码覆盖率,如果不注重覆盖率的提升,那么很有可能会导致开发成员为了单元测试而写单元测试,预期就会与实际情况相差甚远。
保证单元测试代码覆盖率,将会大大降低代码变更带来的 Bug 率,从而节省整体开发成本。
新人问题:为何要写单元测试?
对于初次开始编写单元测试的开发人员,脑中经常会对此表示怀疑:我为什么要去验证一堆我自己写的正确的逻辑?
实际这个问题包含了区分一个一般开发人员和优秀开发人员很重要的一个条件:他是否会反向思考当前逻辑的正确性。有了这种思维,看待问题才会从多个角度入手分析,对问题的本质掌握更加全面。
不要怀疑,坚持写单元测试,因为这本身也是对反向思维的一种锻炼,以笔者的经验,只有当编写过一段时间之后,才会真正认识单元测试的魅力,并且开始非常习惯的在写一段逻辑之后,顺手写了对于它的单元测试。
即使笔者也算很早就开始写单元测试了,但直到写这篇文章,仍然不断在加深对单元测试的认识。
参考
.NET Core中配置 JWT 授认证
本文主要介绍如何在 .NET Core 项目中配置基于 JWT 的 Token 验证。
Swagger使用中的一些注意总结
本文主要记录 Swagger 在使用过程中遇到的一些问题,从而避免再次踩坑。