我有一个扩展Spring的CSRF存储库的类,并在其中编写了自定义实现。它看起来像这样:

public class CustomCookieCsrfTokenRepository implements CsrfTokenRepository {

    @Autowired
    JWKRepository jWKRepository;

    JWK jWK;

    @PostConstruct
    public void init() {
        jWK = jWKRepository.findGlobalJWK(null); // This is custom code, there will always be a valid object returned here
    }

    @Override
    public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) {
        String tokenValue = token == null ? "" : token.getToken();
        log.info("JWK: " + jWK.getPrivateKey());
        // other logics
    }

}


在测试中,我会执行以下操作:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {CustomCookieCsrfTokenRepositoryTest.class, CustomCookieCsrfTokenRepositoryTest.TestConfig.class })
public class CustomCookieCsrfTokenRepositoryTest {

    @TestConfiguration
    static class TestConfig {
        @Bean
        CustomCookieCsrfTokenRepository customCookieCsrfTokenRepository() {
            return new CustomCookieCsrfTokenRepository();
        }
    }

    @Autowired
    CustomCookieCsrfTokenRepository customCookieCsrfTokenRepository;

    @MockBean
    HttpServletRequest request;

    @MockBean
    HttpServletResponse response;

    @MockBean
    RSAUtil rsaUtil;

    @MockBean
    JWKRepository jWKRepository;

    @MockBean
    JWK jWK;

    @Test
    public void saveToken() {
        CsrfToken csrfToken = customCookieCsrfTokenRepository.generateToken(request);
        String privateKey = "some key value";
        when(jWK.getPrivateKey()).thenReturn(privateKey);
        customCookieCsrfTokenRepository.saveToken(csrfToken, request, response);
        // some asserts
    }

}


因此,基本上,同一令牌测试用例实际上被破坏了,说我尝试执行jWK.getPrivateKey()时有一个NullPointer。我试图检查jWK是否为空对象,但不是。我已通过将日志更改为打印jWK对象进行了验证,但未引发任何错误。但是,我试图在测试用例中模拟并返回jWK对象。为什么不起作用?上面的代码有什么问题?任何帮助将不胜感激。

最佳答案

这里有几件事:

1)JWK字段不是@Autowired字段,因此@MockBean对此无效。我们需要在测试中的该字段上使用简单的@Mock

2)在@PostConstruct中,根据jWKRepository.findGlobalJWK(null)的结果进行分配。

3)我们需要模拟该方法:

@Before
private void init(){
   MockitoAnnotations.initMocks(this);
}

@Mock
JWK jWK;

@Test
public void saveToken() {
    when(jWKRepository.findGlobalJWK(null)).thenReturn(jWK);
    ...
}

08-05 05:03