问题描述
大家好
Hi All
我试图在Spring引导应用程序中执行Junit测试,Junit应该测试一些CRUD操作,我使用的是Spring Repositories,特别是JpaRepository.
I’m trying to execute a Junit test in a Spring boot application, the Junit should test some CRUD operations, I’m using Spring Repositories specifically JpaRepository.
存储库评估:
The Repository calss:
package au.com.bla.bla.bla.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import au.com.bla.bla.bla.entity.Todo;
public interface TodoRepository extends JpaRepository<Todo, Integer> {
}
TodoController类
TodoController class
package au.com.bla.bla.bla.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import au.com.bla.bla.bla.entity.Todo;
import au.com.bla.bla.bla.repository.TodoRepository;
import java.util.List;
import java.util.Map;
@RestController
@CrossOrigin
public class TodoController
{
static final String TEXT = "text";
@Autowired
private TodoRepository todoRepository;
...
@RequestMapping(path = "/todo", method = RequestMethod.POST)
public Todo create(@RequestBody Map<String, Object> body)
{
Todo todo = new Todo();
todo.setCompleted(Boolean.FALSE);
todo.setText(body.get(TEXT).toString());
todoRepository.save(todo);
return todo;
}
...
JUnit:
The JUnit:
package au.com.bla.bla.bla.controller;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.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.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import au.com.bla.bla.bla.repository.TodoRepository;
@WebMvcTest(TodoController.class)
@RunWith(SpringRunner.class)
public class TodoControllerTest {
@Autowired
private MockMvc mvc;
@Autowired
private TodoController subject;
@Before
public void setUp() {
}
@Test
public void testCreate() throws Exception {
String json = "{\"text\":\"a new todo\"}";
mvc.perform(post("/todo").content(json)
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(3))
.andExpect(jsonPath("$.text").value("a new todo"))
.andExpect(jsonPath("$.completed").value(false));
assertThat(subject.getTodos()).hasSize(4);
}
...
问题:
Problem:
执行Junit时,我遇到以下异常:
When executing the Junit I end up with this exception:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'todoController': Unsatisfied dependency expressed through field 'todoRepository': No qualifying bean of type [au.com.bla.bla.bla.repository.TodoRepository] found for dependency [au.com.bla.bla.bla.repository.TodoRepository]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [au.com.bla.bla.bla.repository.TodoRepository] found for dependency [au.com.bla.bla.bla.repository.TodoRepository]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
…
有人可以帮忙吗?预先感谢
Can anyone help with this ?Thanks in advance
推荐答案
您的错误实际上是@WebMvcTest
的预期行为.基本上,您有2个选项可以在控制器上执行测试.
Your error is actually the expected behavior of @WebMvcTest
.You basically have 2 options to perform tests on your controller.
使用@WebMvcTest
,将加载一个最小的spring上下文,足以测试Web控制器.这意味着您的存储库不可用于注入:
With @WebMvcTest
, a minimal spring context is loaded, just enough to test the web controllers. This means that your Repository isn't available for injection:
Spring文档 :
假设目标只是为了测试Controller,则应使用@MockBean
作为模拟来注入存储库.
Assuming the goal is just to test the Controller, you should inject your repository as a mock using @MockBean
.
您可能会遇到类似的事情:
You could have something like:
@RunWith(SpringRunner.class)
@WebMvcTest(TodoController.class)
public class TodoControllerTest {
@Autowired
private MockMvc mvc;
@Autowired
private TodoController subject;
@MockBean
private TodoRepository todoRepository;
@Test
public void testCreate() throws Exception {
String json = "{\"text\":\"a new todo\"}";
mvc.perform(post("/todo").content(json)
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(3))
.andExpect(jsonPath("$.text").value("a new todo"))
.andExpect(jsonPath("$.completed").value(false));
Mockito.verify(todoRepository, Mockito.times(1)).save(any(Todo.class));
}
}
2. @SpringBootTest-您可以@Autowire豆
如果要加载整个应用程序上下文,请使用@SpringBootTest
: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
您会有类似的内容:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class TodoControllerTest {
private MockMvc mvc;
@Autowired
TodoController subject;
@Autowired
private WebApplicationContext context;
@Before
public void setup() {
this.mvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void testNoErrorSanityCheck() throws Exception {
String json = "{\"text\":\"a new todo\"}";
mvc.perform(post("/todo").content(json)
.contentType(APPLICATION_JSON)
.accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(3))
.andExpect(jsonPath("$.text").value("a new todo"))
.andExpect(jsonPath("$.completed").value(false));
assertThat(subject.getTodos()).hasSize(4);
}
}
这篇关于无法在Junit测试中自动装配JpaRepository-Spring Boot应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!