gpt4 book ai didi

java - 如何通过 Autowiring 服务测试 spring-boot 上的 Controller 层?

转载 作者:行者123 更新时间:2023-12-01 18:34:14 26 4
gpt4 key购买 nike

我正在尝试在 API 中测试 Controller 的功能。我已经实现了以下名为 ExpertsServiceImpl.java 的服务:


@Service
@RequiredArgsConstructor
public class ExpertsServiceImpl implements ExpertsService{

private final ExpertRepository repository;



@Override
public Experts createExpert(Experts expert) {
return repository.save(expert);
}
@Override
public void deleteExpert(ObjectId id) {
Experts deleted = findExpertById(id);
if(deleted == null) {
throw new ExpertNotFoundException(id);
}
repository.delete(deleted);
}
public Experts findExpertById(ObjectId id) {
Optional<Experts> searchedExpert = repository.findById(id);
if(searchedExpert.get() == null) {
throw new ExpertNotFoundException(id);
}
return searchedExpert.get();
}

这是我的 MongoDB 存储库:

public interface ExpertRepository extends MongoRepository<Experts, ObjectId>{

}

这是我的 Controller 类:


@RestController
@Validated
class ExpertController {

public final ExpertsService service;
public ExpertController(ExpertsService service) {
this.service = service;
}


@PostMapping(path = "/experts/",
consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.APPLICATION_JSON_VALUE}
)
public Experts newExpert(@Valid @RequestBody Experts newExpert) {
return service.createExpert(newExpert);


}

@DeleteMapping("/experts/{id}")
public void deleteBook(@PathVariable ObjectId id) throws Throwable {
service.deleteExpert(id);
}

我正在为我的 Controller 编写以下测试类:

@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = ExpertController.class)
class ExpertControllerTest {
@Autowired
private MockMvc mockMvc;

@Autowired
private ObjectMapper objectMapper;

@Autowired
private ExpertsService expertsService;

@MockBean
private ExpertRepository repository;

Experts demoExpert = new Experts(ObjectId.get(),"Steve Jobs", "Enterpreneur",
Availability.BUSY, Language.CHINESE);

@Before
public void setUp() throws Exception{
expertsService.deleteAll();
expertsService.createExpert(demoExpert);

}

@After
public void tearDown() throws Exception{
expertsService.deleteAll();
}


@Test
public void deleteExpert() throws Exception {
String expertId = demoExpert.getId();
this.mockMvc.perform(MockMvcRequestBuilders
.delete("/experts/{id}", expertId)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk());
}

这会引发此错误:


java.lang.IllegalStateException: Failed to load ApplicationContext

at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:95)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:98)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$5(ClassBasedTestDescriptor.java:337)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:342)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$6(ClassBasedTestDescriptor.java:337)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)

有人知道我该如何解决这个问题吗?我想这与我 Autowiring 服务和模拟存储库有关,但不确定如何解决这个问题。我想 Autowiring 该服务,因为 mock 它对我的测试没有多大意义。有人知道我该怎么做吗?我很感激任何帮助

最佳答案

WebMvcTest 仅初始化 Controller 层,因此不会创建和注入(inject)所有服务/存储库 bean。在你的情况下,问题是

@Autowired
private ExpertsService expertsService;

替换为

@MockBean
private ExpertsService expertsService;

现在您的服务已经有了模拟,您可以只专注于测试 Controller 逻辑。

关于java - 如何通过 Autowiring 服务测试 spring-boot 上的 Controller 层?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60092195/

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