模块化之后测试怎么写?测试能不能访问没有导出的包和包级私有成员?为什么 JUnit 需要 --add-opens?这篇用一个小模块把黑盒、越界访问、白盒三种测试都跑一遍。
文件: ['com/shop/api/Pricing.java', 'com/shop/internal/Tax.java', 'module-info.java'] java --describe-module: com.shop file://<实验目录> | exports com.shop.api | requires java.base mandated | contains com.shop.internal |
编译黑盒测试(--module-path mods --add-modules com.shop,junit 在类路径):rc 0
运行: ('1 tests found | 1 tests successful | 0 tests failed', []) 编译:rc 1
test_bad/ReachInTest.java:1: error: package com.shop.internal is not visible
(package com.shop.internal is declared in module com.shop, which does not export it)
1 error
加 --add-exports com.shop/com.shop.internal=ALL-UNNAMED 之后编译:rc 0
运行(没有 --add-exports): ('1 tests found | 0 tests successful | 1 tests failed', ['=> java.lang.IllegalAccessError: class ReachInTest (in unnamed module @0x39fb3ab6) cannot access class com.shop.internal.Tax (in module com.shop) because module com.shop does not export com.shop.internal to unnamed module @0x39fb3ab6'])
['=> java.lang.IllegalAccessError: class ReachInTest (in unnamed module @0x39fb3ab6) cannot access class com.shop.internal.Tax (in module com.shop) because module com.shop does not export com.shop.inter']
运行(加 --add-exports): ('1 tests found | 1 tests successful | 0 tests failed', []) 编译(--add-modules com.shop --patch-module com.shop=test_white --add-reads com.shop=ALL-UNNAMED):rc 0
运行(没有 --add-opens): ('4 tests found | 0 tests successful | 4 tests failed', ['│ ├─ of() ✘ class org.junit.platform.commons.util.ReflectionUtils cannot access class com.shop.internal.TaxTest (in module com.shop) because module com.shop does not export com.shop.internal to unnamed module @c8e4bb0', '│ ├─ inst() ✘ class org.junit.platform.commons.util.ReflectionUtils cannot access class com.shop.internal.TaxTest (in module com.shop) because module com.shop does not export com.shop.internal to unnamed module @c8e4bb0', '│ └─ secretIsPackagePrivate() ✘ class org.junit.platform.commons.util.ReflectionUtils cannot access class com.shop.internal.TaxTest (in module com.shop) because module com.shop does not export com.shop.internal to unnamed module @c8e4bb0'])
['│ │ └─ gross() ✘ Unable to make void com.shop.api.PricingTest.gross() accessible: module com.shop does not "opens com.shop.api" to unnamed module @c8e4bb0', '│ ├─ of() ✘ class org.junit.platform.commons.util.ReflectionUtils cannot access class com.shop.internal.TaxTest (in module com.shop) because module com.shop does not export com.shop.internal to unnamed module @c8e4bb0', '│ ├─ inst() ✘ class org.junit.platform.commons.util.ReflectionUtils cannot access class com.shop.internal.TaxTest (in module com.shop) because module com.shop does not export com.shop.internal to unnamed module @c8e4bb0', '│ └─ secretIsPackagePrivate() ✘ class org.junit.platform.commons.util.ReflectionUtils cannot access class com.shop.internal.TaxTest (in module com.shop) because module com.shop does not export com.shop.internal to unnamed modu']
运行(加 --add-opens com.shop/com.shop.internal=ALL-UNNAMED 与 com.shop/com.shop.api=ALL-UNNAMED): ('4 tests found | 4 tests successful | 0 tests failed', [])
['├─ JUnit Platform Suite ✔', '├─ JUnit Jupiter ✔', '│ ├─ PricingTest ✔', '│ │ └─ gross() ✔', '│ └─ TaxTest ✔', '│ ├─ of() ✔', '│ ├─ inst() ✔', '│ └─ secretIsPackagePrivate() ✔'] 编译:rc 0
运行: ('4 tests found | 4 tests successful | 0 tests failed', [])