Некорректная работа JUnit в Spring Boot
Есть простейшее Spring Boot приложение:
@SpringBootApplication
@RestController
@EnableAutoConfiguration
public class DemoApplication {
@RequestMapping("/")
String home() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Есть заготовка простейшего юнит-теста к нему:
@RunWith(SpringRunner.class)
@SpringBootTest
class DemoApplicationTests {
@Test
public void contextLoads() throws URISyntaxException {
RestTemplate restTemplate = new RestTemplate();
final String baseUrl = "http://localhost:"+80;
URI uri = new URI(baseUrl);
ResponseEntity<String> result = restTemplate.getForEntity(uri, String.class);
String s= result.getBody();
}
}
При запуске юнит-теста он пишет ошибку, что невозможно подключиться к серверу. Но, если запустить проект в "обычном" режиме, всё работает отлично и на экране браузера отображается "Hello World".
Использую Eclipse и JUnit 4.
Что я делаю не так? Вывод в консоли ("обычный" режим):
2020-02-14 23:32:50.588 INFO 8220 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication on DESKTOP-UACCO14 with PID 8220 (D:\eclipse-W\demo\target\classes started by Егор in D:\eclipse-W\demo)
2020-02-14 23:32:50.598 INFO 8220 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2020-02-14 23:32:51.920 INFO 8220 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 80 (http)
2020-02-14 23:32:51.934 INFO 8220 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-02-14 23:32:51.934 INFO 8220 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-02-14 23:32:52.051 INFO 8220 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-02-14 23:32:52.052 INFO 8220 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1371 ms
2020-02-14 23:32:52.305 INFO 8220 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-02-14 23:32:52.564 INFO 8220 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 80 (http) with context path ''
2020-02-14 23:32:52.569 INFO 8220 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 2.499 seconds (JVM running for 3.513)
Вывод в консоли (запуск в режиме юнит-теста):
2020-02-14 23:21:32.571 INFO 7748 --- [ main] com.example.demo.DemoApplicationTests : Starting DemoApplicationTests on DESKTOP-UACCO14 with PID 7748 (started by Егор in D:\eclipse-W\demo)
2020-02-14 23:21:32.574 INFO 7748 --- [ main] com.example.demo.DemoApplicationTests : No active profile set, falling back to default profiles: default
2020-02-14 23:21:50.483 INFO 7748 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-02-14 23:21:51.376 INFO 7748 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 19.882 seconds (JVM running for 23.085)
2020-02-14 23:22:37.781 INFO 7748 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
Сообщение об ошибке в JUnit Runner:
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:80": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect
Ответы (1 шт):
В общем разобрался сам. В моём случае нужно вместо @SpringBootTest использовать аннотацию @WebMvcTest в сочетании с классом MockMvc.
Код рабочего юнит-теста:
import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
@RunWith(SpringRunner.class)
@WebMvcTest(DemoApplication.class)
class DemoApplicationTests {
private static final String ROOT_URL = "";
private static final String HELLO_WORLD = "Hello World!";
@Autowired
private MockMvc mvc;
@Test
public void contextLoads() throws Exception {
MvcResult result = mvc.perform(get(ROOT_URL)).andReturn();
String s = result.getResponse().getContentAsString();
assertTrue(s.equals(HELLO_WORLD));
}
}
Источники, где я нашёл решение: