0%

JUnit汇总

@RunWith

查阅官方API文档如下:
When a class is annotated with @RunWith or extends a class annotated with @RunWith, JUnit will invoke the class it references to run the tests in that class instead of the runner built into JUnit. We added this feature late in development. While it seems powerful we expect the runner API to change as we learn how people really use it. Some of the classes that are currently internal will likely be refined and become public. For example, suites in JUnit 4 are built using RunWith, and a custom runner named Suite:

1
2
3
4
@RunWith(Suite.class)
@SuiteClasses(ATest.class, BTest.class, CTest.class)
public class ABCSuite {
}

翻译:当一个类被@RunWith所注解或者继承了一个被@RunWith注解的父类,那么Junit将会调用到这个类它所引用到的测试类,而不是通过Junit构建的runner(运行器)去调用。

可以参考:
https://www.tutorialspoint.com/junit/junit_suite_test.htm
https://www.codejava.net/testing/junit-test-suite-example-how-to-create-and-run-test-suite-in-command-line-and-eclipse

结合Spring上下文做测试

在以往的Spring项目中,很多同学可能没有做到真正的单元测试,可能都是基于测试环境启动整个应用来针对功能做测试,这种方式其实效率是非常低的,利用JUnit的特性做Spring的单元测试可以如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/*
* 代码来源:https://my.oschina.net/itblog/blog/1550753
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class UserManagerTest {
  @Autowired
  ApplicationContext ctx;

  @Test
  public void testAddUser() {
    try {
      UserManager userManager = ctx.getBean(UserManager.class);
      userManager.addUser();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

上面的例子是指定一个Spring上下文配置文件的方式进行单元测试,这样子就加载很多本次单元测试不用到的注入,Spring官方文档给出了更加高效的方案:
Context Configuration with Annotated Classes
To load an ApplicationContext for your tests by using annotated classes (see Java-based container configuration), you can annotate your test class with @ContextConfiguration and configure the classes attribute with an array that contains references to annotated classes. The following example shows how to do so:
翻译:使用@ContextConfiguration里面的classes属性来指定加载的配置类信息

1
2
3
4
5
6
@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from AppConfig and TestConfig
@ContextConfiguration(classes = {AppConfig.class, TestConfig.class})
public class MyTest {
// class body...
}

If you omit the classes attribute from the @ContextConfiguration annotation, the TestContext framework tries to detect the presence of default configuration classes. Specifically, AnnotationConfigContextLoader and AnnotationConfigWebContextLoader detect all static nested classes of the test class that meet the requirements for configuration class implementations, as specified in the @Configuration javadoc. Note that the name of the configuration class is arbitrary. In addition, a test class can contain more than one static nested configuration class if desired. In the following example, the OrderServiceTest class declares a static nested configuration class named Config that is automatically used to load the ApplicationContext for the test class:
翻译:此外,Spring官方还提供了更加简要的方式,可以省略掉@ContextConfiguration里面的classes属性。因为TestContext框架会去检测默认存在的配置类,特别是,测试类中存在的内部静态配置类,比如下面代码中的静态配置类将被加载到测试的Spring上下文中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from the
// static nested Config class
@ContextConfiguration
public class OrderServiceTest {

@Configuration
static class Config {

// this bean will be injected into the OrderServiceTest class
@Bean
public OrderService orderService() {
OrderService orderService = new OrderServiceImpl();
// set properties, etc.
return orderService;
}
}

@Autowired
private OrderService orderService;

@Test
public void testOrderService() {
// test the orderService
}

基于SpringBoot的单元测试

1
2
3
4
5
6
7
8
9
10
11
@RunWith(SpringRunner.class)
@SpringBootTest
@Import(MyTestsConfiguration.class)
public class MyTests {

@Test
public void exampleTest() {
...
}

}

指定类别的方式去进行多个单元测试

https://github.com/junit-team/junit4/wiki/Categories

可以自定义参数化的单元测试

https://github.com/junit-team/junit4/wiki/Parameterized-tests
这个暂时还来不及分析场景和用例

更多的单元测试尽在https://github.com/junit-team/junit4/wiki