[JUnit] JUnit5 基础 3 - 依赖注入,假设(assume),开启/禁用测试 与 嵌套测试
Posted GoldenaArcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JUnit] JUnit5 基础 3 - 依赖注入,假设(assume),开启/禁用测试 与 嵌套测试相关的知识,希望对你有一定的参考价值。
[JUnit] JUnit5 基础 3 - 依赖注入,假设(assume),开启/禁用测试 与 嵌套测试
Dependency Injection
在 Junit5 之前,Junit 对于在测试构造函数或方法中传参数支持不是很好,但是 Junit5 允许向构造函数与方法中传入元数据,因此也能在测试方法/构造函数中使用依赖注入。
如 Junit5 内置的 TestInfo
对象,就可以通过 DI 的方式在运行时获取:
package com.example;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
@DisplayName("App Test with spaces")
public class AppTest
{
@BeforeAll
public static void beforeAll(TestInfo testInfo){
System.out.println("********* execute beforeAll() *********");
System.out.println("Display name - " + testInfo.getDisplayName());
System.out.println("Test Class - " + testInfo.getTestClass());
System.out.println("Test Method - " + testInfo.getTestMethod());
System.out.println("****************************************");
}
public AppTest(TestInfo testInfo) {
System.out.println("********* execute constructor **********");
System.out.println("Display name - " + testInfo.getDisplayName());
System.out.println("Test Class - " + testInfo.getTestClass());
System.out.println("Test Method - " + testInfo.getTestMethod());
System.out.println("****************************************");
}
@BeforeEach
public void BeforeEach(TestInfo testInfo) {
System.out.println("********* execute beforeEach() *********");
System.out.println("Display name - " + testInfo.getDisplayName());
System.out.println("Test Class - " + testInfo.getTestClass());
System.out.println("Test Method - " + testInfo.getTestMethod());
System.out.println("****************************************");
}
@Test
public void testOne(TestInfo testInfo) {
System.out.println("********* execute testOne() ***********");
System.out.println("Display name - " + testInfo.getDisplayName());
System.out.println("Test Class - " + testInfo.getTestClass());
System.out.println("Test Method - " + testInfo.getTestMethod());
System.out.println("****************************************");
}
}
运行结果为:
通过依赖注入,TestInfo
在运行时对于不同的显示名称、方法能够自行判断,而非用户手动声明的方式去进行判断。
假设(Assume)
除了 断言(assert) 之外,Junit5 也能通过 假设(assume) 对值进行判断。
assumeTrue & assumeFalse
package com.example;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import org.junit.jupiter.api.Test;
public class AppTest
{
@Test
void testAssumeTrue() {
int num1 = 1, num2 = 1;
assumeTrue(num1 == num2);
}
@Test
void testAssumeTrueFail() {
int num1 = 1, num2 = 1;
assumeTrue(num1 != num2, "assumption fail");
}
@Test
void testAssumeFalse() {
int num1 = 1, num2 = 1;
assumeFalse(num1 != num2);
}
}
运行结果:
assumeThat
package com.example;
import static org.junit.jupiter.api.Assumptions.assumingThat;
import org.junit.jupiter.api.Test;
public class AppTest
{
@Test
void testAssumeThat1() {
int val1 = 1, val2 = 0;
assumingThat(val1 == val2, () -> {
System.out.println("working on this part");
});
}
@Test
void testAssumeThat2() {
int val1 = 1, val2 = 0;
assumingThat(val1 != val2, () -> {
System.out.println("will skip this part");
});
System.out.println("still print this line");
}
}
运行结果:
assume 的应用场景
乍一看 assume
和 assert
好像没有什么区别,但是 assumeTrue
和 assumeFalse
中,testAssumeTrueFail()
函数的旁边不是一个 ❌,而是一个 ❔,这是因为 Junit5 跳过了这个方法,直接进行下一个测试方法。而使用 assert
的话,Junit5 就会判断这个测试方法失败,直接返回 ❌。
assumingThat
方法中,差别更加明显,尽管 testAssumeThat2()
中 assumingThat
的判断是错误的,但是该测试方法并没有终止,而是跳过了 assumingThat
中的内容,直接跳到了下一行代码,并且进行了输出。
这也使得 assume
的应用场景较为的明确:它可以用于对不同环境的测试,如:
package com.example;
import static org.junit.jupiter.api.Assumptions.assumingThat;
import org.junit.jupiter.api.Test;
public class AppTest
{
@Test
void testAssumeTha2() {
System.setProperty("ENV", "DEV");
assumingThat("DEV".equals(System.getProperty("ENV")), () -> {
// 使用 assert 进行测试
});
System.out.println("运行所有环境下都要运行的测试");
}
}
开启与禁用测试
禁用测试
@Disabled
注释可以用来禁用测试:
package com.example;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@Disabled
public class AppTest
{
@Test
void test1() {
assertTrue(1 == 2);
}
@Test
void test2() {
assertTrue(1 == '1');
}
}
其运行结果如下:
可以从左边的测试界面看到,Junit 直接跳过了所有的测试,没有表示成功也没有表示失败。
同样,@Disabled
也可以用在方法上,当挂载在方法上是,它会跳过当前的测试方法,进行下一个测试。
开启/禁用 OS
该方法可以使得测试方法不在具体的 OS 上运行,如:
package com.example;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
public class AppTest
{
@Test
void test1() {
System.out.println("Linux/MacOS/Windows");
}
@DisabledOnOs(OS.MAC)
@Test
void test2() {
System.out.println("Linux/Windows");
}
@DisabledOnOs(OS.WINDOWS)
@Test
void test3() {
System.out.println("Linux/MacOS");
}
}
我的系统是 Windows,所以 test3()
就会被禁用了:
有 @DisabledOnOs()
,同样也有 @EnabledOnOs()
。
开启/禁用 JRE
这条与开启禁用 OS 的配置相似,都是让测试方法在指定的 JRE 环境下运行。
系统属性条件
这指的是 SystemProperty
变量,对应的注释为 @DisabledIfSystemProperty
和 @EnabledIfSystemProperty
。
package com.example;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
public class AppTest
{
@DisabledIfSystemProperty(named="os.name", matches="Windows 10")
@Test
void test2() {
System.out.println("not windows 10");
}
}
运行结果:
环境变量条件
与系统属性条件的使用方法相似,其注解为:@DisabledIfEnvironmentVariable
与 @EnabledIfEnvironmentVariable
。
嵌套测试
嵌套测试,即使用匿名类进行嵌套测试。
package com.example;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
public class AppTest
{
@Test
void test() {
System.out.println("outer");
}
@Nested
class NestedClass {
@Test
void test2() {
System.out.println("nested inner");
}
}
}
运行结果如下:
以上是关于[JUnit] JUnit5 基础 3 - 依赖注入,假设(assume),开启/禁用测试 与 嵌套测试的主要内容,如果未能解决你的问题,请参考以下文章
[JUnit] JUnit5 基础 1 - Junit5 结构 与 断言的使用