我正在用Mockito寫一個JUnit。但在線間諜方法調用實際方法
when(encryptDecryptUtil.getKeyFromKeyStore(any(String.class))).thenReturn(keyMock);
它調用實際的方法,這是導致測試失敗。有趣的是,當when()... thenReturn()statemnts被執行時,它直接在測試用例開始時進行實際調用。你能告訴我如何解決這個問題嗎?我的測試如下
@Test
public void testDecryptData_Success() throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
encryptDecryptUtil = spy(new EncryptDecryptUtil());
Key keyMock = Mockito.mock(Key.class);
when(encryptDecryptUtil.getKeyFromKeyStore(any(String.class))).thenReturn(keyMock);
String inputData = "TestMessage";
String version = GetPropValues.getPropValue(PublisherConstants.KEYSTORE_VERSION);
byte[] enCryptedValue= new byte[] {9,2,5,8,9};
Cipher cipherMock = Mockito.mock(Cipher.class);
when(Cipher.getInstance(any(String.class))).thenReturn(cipherMock);
when(cipherMock.doFinal(any(byte[].class))).thenReturn(enCryptedValue);
String encryptedMessage = encryptDecryptUtil.encryptData(inputData);
assert(encryptedMessage.contains(version));
assertTrue(!encryptedMessage.contains(inputData));
}
在第三行它自己,它調用實際的方法。主代碼如下。
public class EncryptDecryptUtil {
private String publicKeyStoreFileName =
GetPropValues.getPropValue(PublisherConstants.KEYSTORE_PATH);
private String pubKeyStorePwd = "changeit";
private static final String SHA1PRNG = "SHA1PRNG";
private static final String pubKeyAlias="jceksaes";
private static final String JCEKS = "JCEKS";
private static final String AES_PADDING = "AES/CBC/PKCS5Padding";
private static final String AES = "AES";
private static final int CONST_16 = 16;
private static final int CONST_0 = 0;
private static final String KEY_STORE = "aes-keystore";
private static final String KEY_STORE_TYPE = "jck";
private static final Logger logger = Logger.getLogger(KafkaPublisher.class);
public Key getKeyFromKeyStore(String keystoreVersion) {
KeyStore keyStore = null;
Key key = null;
try {
keyStore = KeyStore.getInstance(JCEKS);
FileInputStream stream = null;
stream = new FileInputStream(publicKeyStoreFileName+KEY_STORE+PublisherConstants.UNDERSCORE+keystoreVersion+PublisherConstants.DOT+KEY_STORE_TYPE);
keyStore.load(stream, pubKeyStorePwd.toCharArray());
stream.close();
key = keyStore.getKey(pubKeyAlias, pubKeyStorePwd.toCharArray());
} catch (KeyStoreException e) {
e.printStackTrace();
}
catch (FileNotFoundException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (CertificateException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (IOException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
}
return key;
}
public String encryptData(String data) {
String keystoreVersion = GetPropValues.getPropValue(PublisherConstants.KEYSTORE_VERSION);
SecretKey secKey = new SecretKeySpec(getKeyFromKeyStore(keystoreVersion).getEncoded(), AES);
String base64EncodedEncryptedMsg = null;
Cipher cipher = null;
try { ------- Logic -------------------}
catch() { }
}
}
感謝您的解決方案..!我以前嘗試過doReturn(..),但以錯誤的方式嘗試過。 關於你的建議,我明白,但不幸的是,這個類不使用任何Apring或高級框架。我只寫了基本的Java程序,這使得編寫junit非常困難。它有一堆使用新的Constructor()初始化的對象;這是一個很大的痛苦。我試圖用powermockito來取得它不成功,所以我去了SPY()。如果你知道有更好的方法來用new()來完成對這個對象的初始化,我會明白這一點 – user3452558