在 Spring Boot 中使用 JUnit5 和 Mockito 进行集成测试

程序

我在春季启动时遇到控制器测试问题。我在任何地方都找不到示例如何使用 junit5 和 mockito 进行 spring 控制器集成测试。我写过这样的东西:

@ExtendWith(SpringExtension.class)
@WebMvcTest(UserController.class)
class UserControllerTest {

  @MockBean
  private UserService userService;

  @Autowired
  private MockMvc mockMvc;

  private User user;

  @BeforeEach
  void init(){
    user = getUserData();
  }

  private User getUserData(){
    User u = new User();
    u.setId(0);
    return u;
  }

  @Test
  void shouldReturnDefaultMessage() throws Exception {
    int id = 0;

    when(userService.findById(id)).thenReturn(Optional.ofNullable(user));
    this.mockMvc.perform(get("/user/" + id))
        .andDo(print())
        .andExpect(status()
          .isOk())
        .andExpect(jsonPath("$.id", is(String.valueOf(id))));
  }
}

UserController.class:

@RestController
@RequestMapping(value = "/user")
  public class UserController {
  private final UserService userService;
  private final ConverterContext converterContext;

  public UserController(UserService userService,
                      ConverterContext converterContext) {
    this.userService = userService;
    this.converterContext = converterContext;
  }

  @RequestMapping(value = "", method = RequestMethod.GET)
  public ResponseEntity get(@RequestParam(value = "username", required = false) @ExistAccountWithUsername String username) {
    if(!username.isEmpty()){
        return getUsersByUsername(username);
    }
    return getAllUsers();
  }

  private ResponseEntity getUsersByUsername(String username){
    Optional<User> user = userService.findByUsername(username);
    ShowUserDto showUserDto = convert(user.get());
    return new ResponseEntity<>(showUserDto, HttpStatus.OK);
  }

  private ResponseEntity getAllUsers(){
    List<User> users = userService.findAll();
    List<ShowUserDto> showUserDtos = users.stream()
            .map(this::convert)
            .collect(Collectors.toList());
    return new ResponseEntity<>(showUserDtos, HttpStatus.OK);
  }

  @RequestMapping(value = "/{id}", method = RequestMethod.GET)
  public ResponseEntity getById(@PathVariable(value = "id") int id) {
    Optional<User> user = userService.findById(id);
    if (user.isPresent()) {
        ShowUserDto userDto = convert(user.get());
        return new ResponseEntity<>(userDto, HttpStatus.OK);
    } else {
        return new ResponseEntity<>(new ResourceNotFoundMessage("user", "id", id), HttpStatus.NOT_FOUND);
    }
  }

  private ShowUserDto convert(User user) {
    return converterContext.getConverter(ConverterShowUserDto.class).convert(user);
  }

}

我得到错误:

java.lang.IllegalStateException: Failed to load ApplicationContext

at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:99)
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:246)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:97)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$null$2(ClassTestDescriptor.java:204)
at org.junit.jupiter.engine.descriptor.JupiterTestDescriptor.executeAndMaskThrowable(JupiterTestDescriptor.java:145)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$invokeTestInstancePostProcessors$3(ClassTestDescriptor.java:204)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.invokeTestInstancePostProcessors(ClassTestDescriptor.java:203)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateAndPostProcessTestInstance(ClassTestDescriptor.java:189)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$1(ClassTestDescriptor.java:181)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:80)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:60)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$2(HierarchicalTestExecutor.java:92)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:92)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$2(HierarchicalTestExecutor.java:92)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:92)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:51)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController' defined in file [D:\zzz\target\classes\pl\xxx\zzz\controller\user\UserController.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'pl.xxx.zzz.converter.ConverterContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:732)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:197)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1276)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1133)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:139)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 61 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'pl.xxx.zzz.converter.ConverterContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1509)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:818)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:724)
... 79 more
pvpkiran

当我按原样运行你的代码时,这是我得到的错误

引起的:

org.springframework.beans.factory.NoSuchBeanDefinitionException: 没有可用的“in.phani.springboot.camel.controller.UserService”类型的合格 bean:预计至少有 1 个 bean 有资格作为自动装配候选。依赖注解:{@org.springframework.beans.factory.annotation.Autowired(required=true)}

这意味着 spring 正在搜索 UserService bean。即您的模拟未被采用。

使用@MockBean代替@Mock

 @MockBean
 private UserService userService;

那应该可以解决问题。在高层次上,基本区别是

@Mock是来自 Mockito 的一个类。这只是一个模拟,它没有做任何事情。
@MockBean它允许在 Spring ApplicationContext 中添加 Mockito 模拟。(这正是您的情况所缺少的)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Kotlin和JUnit5中测试Spring Boot缓存

使用Spring Boot和JUnit5在Intellij中终止所有测试

使用JUnit5和Spring-boot-starter-parent时不执行任何测试

使用Mockito和jUnit5的SpringBoot Controller测试失败,因为Spring无法创建可加载属性的PropertyService类的bean?

使用Spring Boot和Spock进行集成测试

如何使用 Mockito 进行模拟并使用 Junit5 断言抛出的异常和消息?

在 Spring Boot 中使用 Junit 5 进行测试失败

如何使用Mockito和JUnit在Spring Boot中测试DELETE方法

无法使用Spring Boot Gradle插件通过依赖项管理执行junit5测试

使用Spring Boot进行黄瓜集成测试

使用Spring Boot进行Kotlin集成测试

使用Spring Boot和Mockito进行模拟对象方法调用

如何使用 spring boot 和 mockito 对控制器方法进行单元测试

如何在Web安全和服务usnig Junit5和Mockito中使用SpringBootTest?

使用Junit5进行Gradle多项目集成测试

我是否需要使用 Kotlin Junit5 和 Spring Boot 将 Spring 注释复制到内部类?

带Spring Boot的Junit 5:何时使用@ExtendWith Spring或Mockito?

使用异步作业和请求范围 bean 进行 Spring Boot 集成测试

使用WireMock和Eureka进行的Spring Boot集成测试失败,显示“无可用实例”

无法使用带有Spring Boot,JUnit5和Kotlin的@TestPropertySource加载test-properties.yaml文件

使用Junit5在Spring Boot应用程序中测试服务层时如何避免数据库连接

如何使用Junit和Mockito测试Spring验证器

如何使用带的Mockito JUnit5

使用Eureka服务进行集成测试Spring Boot服务

使用Spring Boot 1.4错误与ZonedDateTime进行集成测试

使用 mockito 和 Junit5 使用参数模拟静态 void 方法

Spring Boot JUnit5:TypeCast 模拟

尝试使用junit5和mockito模拟byte []值时为空值

使用spring boot和testng运行集成测试时出错