【问题标题】:Mock JWT Utils to validate Token模拟 JWT 实用程序来验证令牌
【发布时间】:2020-10-10 23:43:49
【问题描述】:

我想为此端点创建 JUnkt 测试:

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @PostMapping("reset_token")
    public ResponseEntity<?> resetToken(@Valid @RequestBody ResetPasswordTokenDTO resetPasswordTokenDTO, BindingResult bindResult) {

        final String login = jwtTokenProvider.getUsername(resetPasswordTokenDTO.getResetPasswordToken());
    }

完整代码:Github

JUnit 测试:

@Test
public void resetTokenTest_NOT_FOUND() throws Exception {
    when(usersService.findByResetPasswordToken(anyString())).thenReturn(Optional.empty());

    mockMvc.perform(post("/users/reset_token")
            .contentType(MediaType.APPLICATION_JSON)
            .content(ResetPasswordTokenDTO))
            .andExpect(status().isNotFound());
}

当我运行代码时,我在这一行得到了 NPE:

final String login = jwtTokenProvider.getUsername(resetPasswordTokenDTO.getResetPasswordToken());

如何正确模拟jwtTokenProvider?如您所见,我有一个带有测试data 的文件,我加载了该文件,但未提取令牌。你知道我该如何解决这个问题吗?

【问题讨论】:

    标签: java spring junit junit5 spring-test


    【解决方案1】:

    最直接的方法是使用Mockito 并创建模拟实例并使用构造函数注入将其直接传递给您的控制器类。

    但是,如果您不希望使用构造函数注入(我建议您使用它,因为它更明确),您需要在单独的测试配置类中定义您的 bean

    
    @Profile("test")
    @Configuration
    
    public class TestConfiguration {
        @Bean
        public JwtTokenProvider mockJwtTokenProvider() {
            return Mockito.mock(JwtTokenProvider.class);
        }
    
    }
    
    

    另外,通过@ActiveProfiles("test")将正确的配置文件添加到您的测试类

    【讨论】:

    • 我需要把这个 Java 类放在哪里?
    • 还有其他方法可以在 JUnit 类文件中实现这一点吗?
    • 你也可以把它和测试放在同一个文件中。或者像我之前说的那样使用构造函数注入。
    • 好吧,又是 NPE。还有其他解决方案吗?
    • @PeterPenzov 你是否首先在返回的模拟中设置了存根,使用when(mock.something()).thenReturn(...),还验证模拟是否被正确的值击中。模拟对象默认返回 null,任何链接调用都可能失败
    【解决方案2】:

    您可以考虑直接在您的测试类中使用@MockBean 来模拟您的JwtTokenProvider@MockBean 注释是 Spring-ish 并包含在 spring-boot-starter-test 中。 Spring Boot documentation总结的很好:

    Spring Boot 包含一个 @MockBean 注解,可用于定义 一个 Mockito 模拟你的 ApplicationContext 中的一个 bean。您可以使用 添加新bean或替换单个现有bean的注释 定义。注释可以直接在测试类上使用,在 测试中的字段,或 @Configuration 类和字段。什么时候 在字段上使用时,创建的模拟实例也会被注入。 模拟 bean 在每个测试方法之后都会自动重置。

    @MockBean 注释将使 Spring 在其应用程序上下文中查找现有的 JwtTokenProvider 类型的单个 bean。如果存在,则 mock 将替换该 bean,如果不存在,则在应用程序上下文中添加新的 mock。

    你的测试类应该是这样的:

    import org.springframework.boot.test.mock.mockito.MockBean;
    
    @MockBean
    @Qualifier("xxx") //If there is more than one bean of type JwtTokenProvider
    private JwtTokenProvider jwtTokenProvider;
    
    @Test
    public void resetTokenTest_NOT_FOUND() throws Exception {
    
        when(jwtTokenProvider.getUsername(anyString())).thenReturn(Optional.empty());
    
        mockMvc.perform(post("/users/reset_token")
                .contentType(MediaType.APPLICATION_JSON)
                .content(ResetPasswordTokenDTO))
                .andExpect(status().isNotFound());
    }
    

    您可能还想查看thisthis

    【讨论】:

      猜你喜欢
      • 2019-06-23
      • 2021-12-09
      • 1970-01-01
      • 2017-07-27
      • 2019-10-20
      • 2016-01-17
      • 2018-03-07
      • 2018-10-16
      • 2019-11-01
      相关资源
      最近更新 更多