title: Using JUnit for Code Testing in SpringBoot
date: 2021-08-24 15:30:00
toc: true
category:
- Java
tags: - Java
- SpringBoot
- Unit
- Testing
JUnit is a well-known testing framework in Java. By integrating JUnit + SpringBoot Test, you can use SpringBoot features such as dependency injection in your test programs.
Dependencies#
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
Test Service#
Location: src/main/java/com/example/service/impl/HelloServiceImpl.java
package com.example.service.impl;
@Service
public class HelloServiceImpl implements HelloService {
@Override
public String helloTo(String name) {
// Intentionally create a bug
if ("C++".equals(name))
return "Don't hello to C++";
return StringUtils.hasText(name) ? "HELLO " + name : "HELLO WORLD";
}
}
To test this code, the common way in Java is to manually create the required resources and perform the tests. However, this approach cannot make use of various SpringBoot features. If there are many dependencies involved or if it involves configuration reading, it can be a nightmare:
private HelloService helloService;
@Before
public void setUp() {
helloService = new HelloService();
}
@Test
public void helloTo() {
assertEquals("HELLO WORLD", helloService.helloTo(""));
assertEquals("HELLO WORLD", helloService.helloTo("WORLD"));
assertEquals("HELLO JAVA", helloService.helloTo("JAVA"));
assertEquals("HELLO C++", helloService.helloTo("C++")); // Error
}
Method 1: Annotation-based SpringBoot Startup#
Location: src/test/java/com/example/service/impl/HelloServiceImplTest.java
Key points:
- Use Junit SpringBoot Test framework:
@RunWith(SpringRunner.class)
- Specify the startup entry point:
@SpringBootTest(classes = [SpringBoot Application Entry Class])
After the test is completed, the SpringBoot context will be automatically closed.
package com.example.service.impl;
import com.example.SpringBootTestApplication;
import com.example.service.HelloService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootTestApplication.class)
public class HelloServiceImplTest {
@Autowired
private HelloService helloService;
@Test
public void helloTo() {
assertEquals("HELLO WORLD", helloService.helloTo(""));
assertEquals("HELLO WORLD", helloService.helloTo("WORLD"));
assertEquals("HELLO JAVA", helloService.helloTo("JAVA"));
assertEquals("HELLO C++", helloService.helloTo("C++")); // Error
}
}
Method 2: Explicit SpringBoot Startup#
By using the SpringApplication::run
method, you can start the SpringBoot application and use all its features for testing. However, it is a bit more cumbersome and you must manually close the SpringBootContext
after the test.
package com.example.service.impl;
import com.example.SpringBootTestApplication;
import com.example.service.HelloService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import static org.junit.Assert.assertEquals;
public class HelloServiceImplTest2 {
private ConfigurableApplicationContext context;
private HelloService helloService;
@Before
public void setUp() {
context = SpringApplication.run(SpringBootTestApplication.class);
// Explicitly get the Bean, SpringBoot will automatically inject the required dependencies
helloService = context.getBean(HelloService.class);
}
@After
public void tearDown() {
// Close the SpringBoot application
context.close();
}
@Test
public void helloTo() {
assertEquals("HELLO WORLD", helloService.helloTo(""));
assertEquals("HELLO WORLD", helloService.helloTo("WORLD"));
assertEquals("HELLO JAVA", helloService.helloTo("JAVA"));
assertEquals("HELLO C++", helloService.helloTo("C++")); // Error
}
}