Home  >  Article  >  Java  >  Introduction and use of Spring Boot Junit unit testing

Introduction and use of Spring Boot Junit unit testing

零下一度
零下一度Original
2017-07-16 10:01:561804browse

Unit test (Module test): It is a small piece of code written by the developer to check whether a small and clear function of the code under test is correct. Generally speaking, a unit test is used to determine the behavior of a specific function under a specific condition (or scenario). For example, you might put a large value into a sorted list and then make sure that the value appears at the end of the list. Alternatively, you might remove characters matching a pattern from a string and then confirm that the string indeed no longer contains those characters.

Simply put, unit testing is to test the smallest functional module in your program. In c language it may be a function, in java it may be a method or class.

The purpose is to improve the quality of the code.

Junit, an old technology, is now mentioned again, not for anything else, but to some extent, to illustrate its importance in the project.

Based on my own feelings and experience, if Junit use cases are written completely according to standards and cover most of the business code in the project, it should not be more than half.

I just wrote some posts about SpringBoot some time ago, and now I am taking out Junit and talking about it from several aspects, which can be regarded as a reference for some novices.

Let’s briefly talk about why we should write test cases

1. It can avoid the omission of test points. In order to conduct better testing, it can improve the testing efficiency

2. It can be tested automatically and can be tested and verified before the project is packaged.

3. It can promptly detect the emergence of new problems caused by modifying the code and solve them in time

Then this article will explain how to use Junit from the following points. Junit4 is much more convenient than 3. You can understand the details yourself. The main thing is that version 4 no longer requires the method naming format, and there is no need to inherit TestCase. Everything is Implemented based on annotations.

1. How to use Junit

in the SpringBoot Web project to create an ordinary Java class. In Junit4, there is no need to inherit the TestCase class.

Because we are a Web project, add annotations to the created Java class:

@RunWith(SpringJUnit4ClassRunner.class) // SpringJUnit支持,由此引入Spring-Test框架支持! 
@SpringApplicationConfiguration(classes = SpringBootSampleApplication.class) // 指定我们SpringBoot工程的Application启动类
@WebAppConfiguration // 由于是Web项目,Junit需要模拟ServletContext,因此我们需要给我们的测试类加上@WebAppConfiguration。


Then you can write the test method, The test method can be annotated with the @Test annotation.

In this class, we can directly @Autowired to inject the class instance we want to test as usual.

The following is the complete code:


package org.springboot.sample;

import static org.junit.Assert.assertArrayEquals;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springboot.sample.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

/**
 *
 * @author  单红宇(365384722)
 * @create  2016年2月23日
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringBootSampleApplication.class)
@WebAppConfiguration
public class StudentTest {

  @Autowired
  private StudentService studentService;

  @Test
  public void likeName() {
    assertArrayEquals(
        new Object[]{
            studentService.likeName("小明2").size() > 0,
            studentService.likeName("坏").size() > 0,
            studentService.likeName("莉莉").size() > 0
          }, 
        new Object[]{
            true,
            false,
            true
          }
    );
//   assertTrue(studentService.likeName("小明2").size() > 0);
  }

}


Next, you need to add countless test classes , write countless test methods to ensure the effectiveness of the programs we have developed.

2. Introduction to basic annotations of JUnit


//在所有测试方法前执行一次,一般在其中写上整体初始化的代码 
@BeforeClass

//在所有测试方法后执行一次,一般在其中写上销毁和释放资源的代码 
@AfterClass

//在每个测试方法前执行,一般用来初始化方法(比如我们在测试别的方法时,类中与其他测试方法共享的值已经被改变,为了保证测试结果的有效性,我们会在@Before注解的方法中重置数据) 
@Before

//在每个测试方法后执行,在方法执行完成后要做的事情 
@After

// 测试方法执行超过1000毫秒后算超时,测试将失败 
@Test(timeout = 1000)

// 测试方法期望得到的异常类,如果方法执行没有抛出指定的异常,则测试失败 
@Test(expected = Exception.class)

// 执行测试时将忽略掉此方法,如果用于修饰类,则忽略整个类 
@Ignore(“not ready yet”) 
@Test

@RunWith


There are many Runners in JUnit , they are responsible for calling your test code. Each Runner has its own special functions. You have to choose different Runners to run your test code according to your needs.

If we are simply doing ordinary Java testing and do not involve spring web projects, you can omit the @RunWith annotation, so that the system will automatically use the default Runner to run your code.

3. Parameterized test

The parameterized test provided by Junit needs to use @RunWith(Parameterized.class)

However Because Junit uses @RunWith to specify a Runner, in more cases we need to use @RunWith(SpringJUnit4ClassRunner.class) to test our Spring engineering methods, so we use assertArrayEquals to test the method with multiple possibilities.

The following is a simple example of parameterized testing:


package org.springboot.sample;

import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class ParameterTest {

  private String name;
  private boolean result;

  /**
   * 该构造方法的参数与下面@Parameters注解的方法中的Object数组中值的顺序对应
   * @param name
   * @param result
   */
  public ParameterTest(String name, boolean result) {
    super();
    this.name = name;
    this.result = result;
  }

  @Test
  public void test() {
    assertTrue(name.contains("小") == result);
  }

  /**
   * 该方法返回Collection
   *
   * @return
   * @author SHANHY
   * @create 2016年2月26日
   */
  @Parameters
  public static Collection<?> data(){
    // Object 数组中值的顺序注意要和上面的构造方法ParameterTest的参数对应
    return Arrays.asList(new Object[][]{
      {"小明2", true},
      {"坏", false},
      {"莉莉", false},
    });
  }
}


4. Packaged Test

Normally we write 5 test classes, and we need to execute them one by one.

Packaging testing means adding a new class, configuring other test classes we have written together, and then running this class directly to achieve the purpose of running several other tests at the same time.

The code is as follows:


@RunWith(Suite.class) 
@SuiteClasses({ATest.class, BTest.class, CTest.class}) 
public class ABCSuite {
  // 类中不需要编写代码
}


##5. Use Junit to test the HTTP API interface

We can use this directly to test our Rest API. If the internal unit testing requirements are not very strict, we ensure that the external API is fully tested, because the API will call many internal methods, let's treat it as It's an integration test.

The following is a simple example:


package org.springboot.sample;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

/**
 *
 * @author  单红宇(365384722)
 * @create  2016年2月23日
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringBootSampleApplication.class)
//@WebAppConfiguration // 使用@WebIntegrationTest注解需要将@WebAppConfiguration注释掉
@WebIntegrationTest("server.port:0")// 使用0表示端口号随机,也可以具体指定如8888这样的固定端口
public class HelloControllerTest {

  private String dateReg;
  private Pattern pattern;
  private RestTemplate template = new TestRestTemplate();
  @Value("${local.server.port}")// 注入端口号
  private int port;

  @Test
  public void test3(){
    String url = "http://localhost:"+port+"/myspringboot/hello/info";
    MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>(); 
    map.add("name", "Tom"); 
    map.add("name1", "Lily");
    String result = template.postForObject(url, map, String.class);
    System.out.println(result);
    assertNotNull(result);
    assertThat(result, Matchers.containsString("Tom"));
  }

}


6. Capture output

Use OutputCapture To capture all output after the specified method starts execution, including System.out output and Log log.


OutputCapture needs to be annotated with @Rule, and the instantiated object needs to be decorated with public, as shown in the following code:


@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringBootSampleApplication.class)
//@WebAppConfiguration // 使用@WebIntegrationTest注解需要将@WebAppConfiguration注释掉
@WebIntegrationTest("server.port:0")// 使用0表示端口号随机,也可以具体指定如8888这样的固定端口
public class HelloControllerTest {

  @Value("${local.server.port}")// 注入端口号
  private int port;

  private static final Logger logger = LoggerFactory.getLogger(StudentController.class);

  @Rule
  // 这里注意,使用@Rule注解必须要用public
  public OutputCapture capture = new OutputCapture();

  @Test
  public void test4(){
    System.out.println("HelloWorld");
    logger.info("logo日志也会被capture捕获测试输出");
    assertThat(capture.toString(), Matchers.containsString("World"));
  }
}

The above is the detailed content of Introduction and use of Spring Boot Junit unit testing. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn