无法在Junit测试中自动assemblyJpaRepository – Spring启动应用程序

大家好

我正在尝试在Spring启动应用程序中执行Junit测试,Junit应该测试一些CRUD操作,我正在使用Spring Repositories专门使用JpaRepository。

存储库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 { } 

TodoController类

 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 body) { Todo todo = new Todo(); todo.setCompleted(Boolean.FALSE); todo.setText(body.get(TEXT).toString()); todoRepository.save(todo); return todo; } ... 

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); } ... 

问题:

执行Junit时,我最终遇到此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] … 

有人能帮忙吗 ? 提前致谢

您的错误实际上是@WebMvcTest的预期行为。 您基本上有2个选项可以在控制器上执行测试。

(1)@WebMvcTest – 需要使用@MockBean

使用@WebMvcTest ,可以加载最小的弹簧上下文,足以测试Web控制器。 这意味着您的存储库不可用于注入:

Spring文档 :

@WebMvcTest将自动配置Spring MVC基础结构并将扫描的bean限制为@ Controller,@ ControllerAdvice,@ JsonComponent,Filter,WebMvcConfigurer和HandlerMethodArgumentResolver。

假设重点是测试Controller,您应该使用@MockBean将存储库注入模拟。

你可以有类似的东西:

 @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 bean

如果要加载整个应用程序上下文,请使用@SpringBootTest : http : @SpringBootTest

你有这样的事情:

 @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); } }