Can't Autowire JpaRepository in Junit test - Spring boot application Can't Autowire JpaRepository in Junit test - Spring boot application spring spring

Can't Autowire JpaRepository in Junit test - Spring boot application


Your error is actually the expected behavior of @WebMvcTest.You basically have 2 options to perform tests on your controller.

1. @WebMvcTest - need to use @MockBean

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 documentation:

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

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 - you can @Autowire beans

If you want to load the whole application context, then use @SpringBootTest: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

You'd have something like this:

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