Java 模拟类在运行测试时从不总是给出空指针
我有一个类扩展了Spring的CSRF存储库,并在其中编写了一个自定义实现。看起来有点像这样:Java 模拟类在运行测试时从不总是给出空指针,java,spring,unit-testing,junit,mockito,Java,Spring,Unit Testing,Junit,Mockito,我有一个类扩展了Spring的CSRF存储库,并在其中编写了一个自定义实现。看起来有点像这样: public class CustomCookieCsrfTokenRepository implements CsrfTokenRepository { @Autowired JWKRepository jWKRepository; JWK jWK; @PostConstruct public void init() { jWK = jW
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
}
}
在我的测试中,我会这样做:
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()
时,同一个令牌测试用例实际上会被破坏,说有一个空指针。我试图检查jWK
是否为空对象,但它不是。我已经通过将日志更改为printjWK
对象进行了验证,它没有抛出任何错误。然而,我试图模拟并返回测试用例中的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);
...
}
这里有几件事: 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);
...
}
嗯,是的,你的方法是正确的。我不知道那些错误。但是,这并不能解决问题,我仍然在同一个位置获取null指针。jWK对象是否为null?或者它是模拟的?不确定它是否是模拟的,但它不是空的。我将log语句从
log.info(“JWK:+JWK.getPrivateKey())更改为
tolog.info(“JWK:+JWK”)代码>并且它没有出现问题就通过了这一行。我尝试过的另一件事是在init本身内部返回mock jwk,但这也不起作用。在一个干净的建筑上,一切都很好。嗯,是的,你的方法是正确的。我不知道那些错误。但是,这并不能解决问题,我仍然在同一个位置获取null指针。jWK对象是否为null?或者它是模拟的?不确定它是否是模拟的,但它不是空的。我将log语句从log.info(“JWK:+JWK.getPrivateKey())更改为
tolog.info(“JWK:+JWK”)代码>并且它没有出现问题就通过了这一行。我尝试过的另一件事是在init本身内部返回mock jwk,但这也不起作用。在一个干净的建筑上,一切都很好。