Reputation: 499
I have a class that extends the CSRF repository of the Spring and where I have written a custom implementation. It looks somewhat like this:
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
}
}
And in my tests, I do something like this:
@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
}
}
So basically, the same token test case actually gets broken saying there is a NullPointer when I try to do jWK.getPrivateKey()
. I tried to check if jWK
is the null object but it isn't. I have verified by changing the log to print jWK
object and it didn't throw any error. However, I am trying to mock and return the jWK
object in my test case. Why doesn't this work? What's wrong with the above code? Any help will be appreciated.
Upvotes: 0
Views: 353
Reputation: 26502
There are a few things here:
1) The JWK field is not an @Autowired
field, thus @MockBean
will not work on it. We need to use a simple @Mock
on that field in the test.
2) In the @PostConstruct
it is assigned based on the result of the jWKRepository.findGlobalJWK(null)
.
3) We need to mock that method:
@Before
private void init(){
MockitoAnnotations.initMocks(this);
}
@Mock
JWK jWK;
@Test
public void saveToken() {
when(jWKRepository.findGlobalJWK(null)).thenReturn(jWK);
...
}
Upvotes: 2