gpt4 book ai didi

java - 无法在 Junit 测试中 Autowiring JpaRepository - Spring 启动应用程序

转载 作者:搜寻专家 更新时间:2023-10-31 08:16:29 25 4
gpt4 key购买 nike

大家好

我正在尝试在 Spring boot 应用程序中执行 Junit 测试,Junit 应该测试一些 CRUD 操作,我正在使用 Spring Repositories,特别是 JpaRepository。

存储库类:

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 类

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:

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 时,我遇到了这个异常:

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 个选项可以在您的 Controller 上执行测试。

1。 @WebMvcTest - 需要使用@MockBean

使用@WebMvcTest,加载最小的spring 上下文,刚好足以测试web Controller 。这意味着您的存储库不可用于注入(inject):

Spring documentation :

@WebMvcTest will auto-configure the Spring MVC infrastructure and limit scanned beans to @Controller, @ControllerAdvice, @JsonComponent, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver.

假设目标只是测试 Controller ,您应该使用 @MockBean 将您的存储库作为模拟注入(inject)。

你可以有这样的东西:

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

如果你想加载整个应用上下文,那么使用@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);
}
}

关于java - 无法在 Junit 测试中 Autowiring JpaRepository - Spring 启动应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40064988/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com