Unable to create JUnit Test for Spring Boot Controller

China☆狼群 提交于 2021-01-29 09:36:56

问题


I am trying to write a test for a simple Controller in SpringBoot application. However, I am receiving errors due to bean creations for my TopicRepository and TopicController. I had referenced a tutorial and am little new to Spring boot development so not sure exactly how it works. How can I make the test work?

ControllerTest

@RunWith(SpringRunner.class)
@WebMvcTest(TopicController.class)
public class TopicControllerTest {

     @Autowired
        private MockMvc mvc;

        @MockBean
        private TopicService topicService;

        @Test
        public void whenGetTopics_returnJSONArray()
          throws Exception {


            Topic topic = new Topic("b","b name", "b descp");

            List<Topic> allTopics = new ArrayList<>();
            allTopics.add(topic);

            Mockito.when(topicService.getAllTopics()).thenReturn(allTopics);

            mvc.perform(get("/topics")
              .contentType(MediaType.APPLICATION_JSON))
              .andExpect(status().isOk())
              .andExpect(jsonPath("$[0].id", is(topic.getId())));

        }       
}

Controller

@RestController
public class TopicController {

    @Autowired
    private TopicService topicService; //inject the topicService as a dependency

    @Autowired
    private TopicRepository topicRepository;


    @RequestMapping("/topics")
    public List<Topic> getAllTopics() {
        return topicService.getAllTopics();

    }


    @RequestMapping("/topics/{name}")
    public Topic getTopic(@PathVariable String name) {
        return topicService.getTopic(name);
    }


    @RequestMapping(method=RequestMethod.POST, value= "/topics")
    public void addTopic(@RequestBody Topic topic) {
        topicService.addTopic(topic);
    }


    @RequestMapping(method=RequestMethod.PUT, value = "/topics/{Id}")
    public void updateTopic(@RequestBody Topic topic, @PathVariable String Id){
        topicService.updateTopic(topic, Id);
    }

}

TopicRepository

public interface TopicRepository extends CrudRepository<Topic, String>{

}

The errors I am getting are

UnsatisfiedDependencyException: Error creating bean with name 'topicController': Unsatisfied dependency expressed through field 'topicRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.nkamanoo.springbootstarter.repository.TopicRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}


回答1:


You need to annotate your test class with @SpringBootTest so it will create all defined beans and start your app to run test cases.

In your code:

@RunWith(SpringRunner.class)
@WebMvcTest(TopicController.class)
@SpringBootTest
public class TopicControllerTest {
}



回答2:


Springboot automatically scans all packages that follows the base package name. Example, if your fresh springboot project has the main class residing in a package com.example.project.

Then your

entities,repository,service,controller
class all need be group in a package which follows the same package structure, if you group your classes in packages, so springboot automatically scans the packages perform automatic dependency injection when, @Autowired is used to perform dependency injection.

So therefore, you other package names should be grouped as follows:

  • com.example.project.entities
  • com.example.project.repositories
  • com.example.project.services
  • com.example.project.controller

This solves the problem of {@org.springframework.beans.factory.annotation.Autowired(required=true)}



来源:https://stackoverflow.com/questions/60220058/unable-to-create-junit-test-for-spring-boot-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!