问题
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,controllerclass 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