gpt4 book ai didi

java - 如何在 Spring Boot 中将 @MockBean 与 JUnit 5 一起使用?

转载 作者:行者123 更新时间:2023-11-30 12:05:27 25 4
gpt4 key购买 nike

我正在尝试在 @WebMvcTest 中使用 @MockBean 和 JUnit 5 编写单元测试。不幸的是,它看起来像 @MockBean 被忽略了,它试图设置完整的持久层,但失败了,这不是我想要的单元测试。

据我所知,@WebMvcTest 根本不应触发应用程序上下文的设置。它应该用于单元测试。所以问题可能是为什么要创建应用程序上下文?

主类:

@SpringBootApplication
@EntityScan("ch.xxx.infop.common.entity")
@EnableJpaRepositories("ch.xxx.infop.dao")
public class ApplicationDispatch {

public static void main(String[] args) {
SpringApplication.run(ApplicationDispatch.class, args);
}

}

调度 Controller :

@RestController
public class DispatchController {

@Autowired
VmRepository vmRepository;

@RequestMapping(path="/compress/{fpId}/{datenlieferantId}/{varianteTyp}")
public String publishMessage(
@PathVariable long fpId,
@PathVariable long datenlieferantId,
@PathVariable VarianteTyp varianteTyp) {

List<Vm> vmList = vmRepository.findByFpIdAndDatenlieferantId(fpId, datenlieferantId);

// ...

return "success";
}

}

调度单元测试:

@ExtendWith(SpringExtension.class)
@WebMvcTest(DispatchController.class)
public class DispatchUnitTest {

@MockBean
private VmRepository vmRepository;

@Autowired
private MockMvc mvc;

@BeforeEach
public void setUp() {
List<Vm> testVmList = new ArrayList<>();
for (long i=0; i<3; i++) {
Vm vm = new Vm();
vm.setId(i);
testVmList.add(vm);
}

when(vmRepository.findByFpIdAndDatenlieferantId(anyLong(), anyLong())).thenReturn(testVmList);
}

@Test
public void contextLoads() throws Exception {
mvc.perform(
MockMvcRequestBuilders.get("/compress/2015/14/J"))
.andExpect(status().isOk())
.andExpect(content().string("success"));
}

}

测试输出:

10:40:57.169 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration ch.xxx.infop.dispatch.ApplicationDispatch for test class ch.xxx.infop.dispatch.DispatchUnitTest
10:40:57.171 [main] DEBUG org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper - @TestExecutionListeners is not present for class [ch.xxx.infop.dispatch.DispatchUnitTest]: using defaults.
10:40:57.171 [main] INFO org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
10:40:57.191 [main] INFO org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@11c9af63, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@757acd7b, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@36b4fe2a, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@574b560f, org.springframework.test.context.support.DirtiesContextTestExecutionListener@ba54932, org.springframework.test.context.transaction.TransactionalTestExecutionListener@28975c28, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@3943a2be, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@343570b7, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@157853da, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@71c3b41, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@236e3f4e, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@3cc1435c]
10:40:57.195 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: context [DefaultTestContext@46fa7c39 testClass = DispatchUnitTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@1fb700ee testClass = DispatchUnitTest, locations = '{}', classes = '{class ch.xxx.infop.dispatch.ApplicationDispatch}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@4f67eb2a key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration, org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration, org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration, org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration, org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration, org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration, org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration, org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration, org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration, org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcSecurityAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebDriverAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1cbbffcd, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@3d51f06e, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@df16af6c, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@498d318c, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@d8cd8528, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@f44e2ec2, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@7e07db1f], resourceBasePath = '', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]], class annotated with @DirtiesContext [false] with mode [null].
10:40:57.342 [main] DEBUG org.springframework.test.context.support.TestPropertySourceUtils - Adding inlined properties to environment: {spring.jmx.enabled=false, org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper=true, server.port=-1}

,------. ,--. ,--. ,--.
| .-. \ `--' ,---. ,---. ,--,--. ,-' '-. ,---. | ,---.
| | \ : ,--. ( .-' | .-. | ' ,-. | '-. .-' | .--' | .-. |
| '--' / | | .-' `) | '-' ' \ '-' | | | \ `--. | | | |
`-------' `--' `----' | |-' `--`--' `--' `---' `--' `--'
`--'
2019-05-24 10:40:57.725 INFO 16844 --- [ main] ch.xxx.infop.dispatch.DispatchUnitTest : Starting DispatchUnitTest on K57176 with PID 16844 (started by ue73011 in C:\devxxx\projekte\infop-dispatch)
2019-05-24 10:40:57.727 INFO 16844 --- [ main] ch.xxx.infop.dispatch.DispatchUnitTest : No active profile set, falling back to default profiles: default
2019-05-24 10:40:58.248 INFO 16844 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2019-05-24 10:40:58.501 INFO 16844 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 238ms. Found 1 repository interfaces.
2019-05-24 10:40:59.589 INFO 16844 --- [ main] faultConfiguringBeanFactoryPostProcessor : No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.
2019-05-24 10:40:59.597 INFO 16844 --- [ main] faultConfiguringBeanFactoryPostProcessor : No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created.
2019-05-24 10:40:59.604 INFO 16844 --- [ main] faultConfiguringBeanFactoryPostProcessor : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.
2019-05-24 10:40:59.670 INFO 16844 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'integrationDisposableAutoCreatedBeans' of type [org.springframework.integration.config.annotation.Disposables] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-05-24 10:40:59.702 INFO 16844 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.hateoas.config.HateoasConfiguration' of type [org.springframework.hateoas.config.HateoasConfiguration$$EnhancerBySpringCGLIB$$82ead0f5] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-05-24 10:41:00.624 WARN 16844 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'vmRepositoryImpl': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available
2019-05-24 10:41:00.630 INFO 16844 --- [ main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-05-24 10:41:00.661 ERROR 16844 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :

***************************
APPLICATION FAILED TO START
***************************

Description:

A component required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found.


Action:

Consider defining a bean of type 'javax.persistence.EntityManagerFactory' in your configuration.

2019-05-24 10:41:00.667 ERROR 16844 --- [ main] o.s.test.context.TestContextManager : Caught exception while allowing TestExecutionListener [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@36b4fe2a] to prepare test instance [ch.xxx.infop.dispatch.DispatchUnitTest@6ed043d3]

最佳答案

经过大量谷歌搜索和尝试错误后,我找到了这个解决方案:

@SpringJUnitConfig
@WebMvcTest(DispatchController.class)
public class DispatchUnitTest {

@Configuration
static class Config {
@Bean
DispatchController dispatchController() {
return new DispatchController();
}
}

@MockBean
private VmRepository vmRepository;

@Autowired
private MockMvc mvc;

@BeforeEach
public void setUp() {
List<Vm> testVmList = new ArrayList<>();
for (long i=0; i<3; i++) {
Vm vm = new Vm();
vm.setId(i);
testVmList.add(vm);
}

when(vmRepository.findByFpIdAndDatenlieferantId(anyLong(), anyLong())).thenReturn(testVmList);
}

@Test
public void contextLoads() throws Exception {
mvc.perform(
get("/compress/2015/14/J"))
.andExpect(status().isOk())
.andExpect(content().string("success"));
}

}

主要变化是使用@SpringJUnitConfig代替@ExtendWith(SpringExtension.class)。这添加了 @ContextConfiguration 就自动检测而言

@Configuration
static class Config {
@Bean
DispatchController dispatchController() {
return new DispatchController();
}
}

我不完全理解为什么这是必要的,以及我在问题中的代码的主要区别是什么。实际上我发现很多例子都没有这个配置。

所以在这个问题上还有一些值得称赞的地方 ;-)。

关于java - 如何在 Spring Boot 中将 @MockBean 与 JUnit 5 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56289179/

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