System Rules:给 java.lang.System 写测试不再抓瞎
文章目录
- System Rules:给 java.lang.System 写测试不再抓瞎
- 1、它解决什么问题
- 2、怎么用
- 3、谁还在用
- 4、适合谁
System Rules:给 java.lang.System 写测试不再抓瞎
System Rules 在 GitHub 上拿了 552 个 Star,数量不算炸裂,但活下来的开源工具里,能持续维护十多年的并不多。这个项目打从早期 JUnit 时代就在用,专门解决一桩很具体的烦人事:测试代码里碰java.lang.System的部分。
1、它解决什么问题
写 Java 单测时,凡是涉及System.exit、System.getProperty、System.setOut、System.setErr、标准输入输出的场景,测试就难写。
直接调System.exit(0),测试进程直接没了。想验证控制台输出,得自己 替换System.out,写完还要在finally里还原回去,否则下一个测试就遭殃。环境变量System.getenv更麻烦,Java 早期版本里几乎是只读的。
System Rules 把这层麻烦全包了。它用 JUnit Rules 机制,每个测试结束自动还原现场,并提供断言接口。ExpectedSystemExit验证退出码,EnvironmentVariables临时改环境变量,ProvideSystemProperty覆盖系统属性,断言一气呵成。
2、怎么用
Maven 依赖加上,scope 设成 test:
<dependency><groupId>com.github.stefanbirkner</groupId><artifactId>system-rules</artifactId><version>1.19.0</version></dependency>测试里直接@Rule一挂,剩下就是写断言。比如测一个调用System.exit(2)的方法:
publicclassMyTest{@RulepublicfinalExpectedSystemExitexit=ExpectedSystemExit.none();@TestpublicvoidexitsWithCode2(){exit.expectSystemExitWithStatus(2);myClass.doSomething();}}不用手工管SecurityManager,不用try/finally还原状态。这就是它存在的意义。
3、谁还在用
System Rules 的核心是 JUnit 4 的 Rule 机制。JUnit 5(Jupiter)出来后,这套机制被 Extension 取代了。作者自己也提供了一个替代品 System Lambda,基于 Java 8,和测试框架解耦,能在 JUnit 5 和 TestNG 里用。
所以现状是这样:老项目里 JUnit 4 写的测试,System Rules 仍然是顺手的选择,迁移成本接近零;新项目用 JUnit 5,直接上 System Lambda 更合适。两个项目同一作者,API 风格相通。
4、适合谁
仍在维护 JUnit 4 老代码、测试里频繁碰java.lang.System的 Java 工程师,这是刚需。新项目用 JUnit 5 的,看一眼 System Lambda,别走这条老路。
CI 方面,作者在 Travis CI(Linux)和 AppVeyor(Windows)上跑了从 Java 6 到 10 的多版本测试。这点对老项目特别友好,毕竟还在用 Java 6 的项目不在少数。贡献代码时,照着.editorconfig写,跑一遍mvnw test,提 PR 就行。
不在少数。贡献代码时,照着.editorconfig写,跑一遍mvnw test,提 PR 就行。