java-在调用Mockito doNothing方法时调用实际方法
作者:互联网
我正在尝试模拟KeyStore类.模拟后,如果加载方法被调用,我不希望发生任何事情.因此,我写了以下几行来实现这一目标.
@PrepareForTest(KeyStoreFactory.class)
@Test
public void should_verify_signature_when_verifySignature_called_with_fileName_and_certificate_details_in_verifySignature_method() throws Exception {
PowerMockito.mockStatic(KeyStoreFactory.class);
KeyStore keyStoreMock = PowerMockito.mock(KeyStore.class);
PowerMockito.when(KeyStoreFactory.getInstance(anyString(), anyString())).thenReturn(keyStoreMock);
Mockito.doNothing().when(keyStoreMock).load(Mockito.any(InputStream.class), Mockito.any(char[].class));
Certificate certificateMock = Mockito.mock(Certificate.class);
when(keyStoreMock.getCertificate(anyString())).thenReturn(certificateMock);
boolean result = signatureUtil.verifySignature("src//test//java//Updates.zip.signed.pkcs7"
, "src//test//java//Updates-retrieved.zip", "Windows-MY,SunMSCAPI,someName");
Assert.assertTrue(result);
}
但是load方法抛出了空指针异常.然后,当我进行调试时,我发现尽管我已指定了嘲笑,但并未调用真正的方法.我在这里做错了什么?请指教.
下面是我编写测试的方法.
@Override
public boolean verifySignature(String filePath, String extractContentsPath, String csvParams)
throws ServiceSDKException {
boolean result = false;
String typeOfCertificateStore = "";
String certificateStoreProvider = "";
String certificateName = "";
SignerInformationVerifier verifier = null;
if (filePath != null && extractContentsPath != null && csvParams != null && !filePath.isEmpty()
&& !extractContentsPath.isEmpty() && !csvParams.isEmpty()) {
try {
String[] receivedParams = csvParams.split(",");
typeOfCertificateStore = receivedParams[0];
certificateStoreProvider = receivedParams[1];
certificateName = receivedParams[2];
} catch (ArrayIndexOutOfBoundsException e) {
throw new ServiceSDKException("csvParams should have type of certificate store, certificate store provider and certificate name respectively", e);
}
try {
Path signedDataFilePath = Paths.get(filePath);
Path pathToExtractContents = Paths.get(extractContentsPath);
KeyStore msCertStore = KeyStoreFactory.getInstance(typeOfCertificateStore, certificateStoreProvider);
msCertStore.load(null, null);
try {
verifier = new JcaSimpleSignerInfoVerifierBuilder()
.setProvider(certificateStoreProvider)
.build(((X509Certificate) msCertStore.getCertificate(certificateName)));
} catch (Exception e) {
throw new ServiceSDKException("Exception occurred when building certificate",e);
}
verify(signedDataFilePath, pathToExtractContents, verifier);
result = true;
} catch (IOException | NoSuchAlgorithmException
| CertificateException e) {
result = false;
throw new ServiceSDKException("Exception occurred while preparing to verify signature " , e);
}
} else {
throw new ServiceSDKException("FilePath,extract contents path or csv params cannot be empty or null");
}
return result;
}
这是整个测试课程:
@RunWith(PowerMockRunner.class)
public class SignatureUtilImplTest {
SignatureUtilImpl signatureUtil = new SignatureUtilImpl();
@PrepareForTest({KeyStoreFactory.class, SignatureUtilImpl.class})
@Test
public void should_verify_signature_when_verifySignature_called_with_fileName_and_certificate_details_in_verifySignature_method() throws Exception {
CMSSignedDataParser spMock = PowerMockito.mock(CMSSignedDataParser.class);
SignerInformationVerifier verifierMock = Mockito.mock(SignerInformationVerifier.class);
SignatureUtilImpl signatureUtilSpy = Mockito.spy(new SignatureUtilImpl());
KeyStore keyStoreMock = PowerMockito.mock(KeyStore.class);
PowerMockito.mockStatic(KeyStoreFactory.class);
PowerMockito.when(KeyStoreFactory.getInstance(anyString(), anyString())).thenReturn(keyStoreMock);
SignerInformation signerInformationMock = Mockito.mock(SignerInformation.class);
Collection<SignerInformation> collection = new ArrayList();
collection.add(signerInformationMock);
Mockito.doCallRealMethod().when(signatureUtilSpy).verifySignature("src/test/java/Updates.zip.signed.pkcs7"
, "src/test/java/Updates-retrieved.zip", "Windows-MY,SunMSCAPI,someName");
Mockito.doNothing().when(signatureUtilSpy).loadKeyStore();
Mockito.doReturn(verifierMock).when(signatureUtilSpy).getSignerInformationVerifier(anyString(), anyString());
Mockito.doReturn(spMock).when(signatureUtilSpy).getDataParser(any(DigestCalculatorProvider.class), any(FileInputStream.class));
Mockito.doReturn(collection).when(spMock).getSignerInfos().getSigners();
Mockito.doReturn(true).when(signerInformationMock).verify(verifierMock);
//PowerMockito.doNothing().when(signatureUtilSpy, "verify", any(Path.class),any(Path.class),any(SignerInformationVerifier.class));
// PowerMockito.doReturn(true).when(signatureUtilSpy, PowerMockito.method(SignatureUtilImpl.class, "verify",Path.class,Path.class, SignerInformationVerifier.class))
// .withArguments(any(Path.class),any(Path.class),any(SignerInformationVerifier.class));
boolean result = signatureUtilSpy.verifySignature("src/test/java/Updates.zip.signed.pkcs7"
, "src/test/java/Updates-retrieved.zip", "Windows-MY,SunMSCAPI,someName");
Assert.assertTrue(result);
}
}
解决方法:
我认为这可以帮助:
在SignatureUtil中创建另一个方法:
public KeyStore loadKeyStore(...){
KeyStore msCertStore = KeyStoreFactory.getInstance(typeOfCertificateStore,certificateStoreProvider);
msCertStore.load(null, null);
}
在您的测试课程中,如下所示.
Mockito.doNothing().when(signatureUtilMock).loadKeyStore(anyString(), anyString());
这是对我有用的代码
package com.foo;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
public class KeyStoreService {
public KeyStoreService(){
}
public void load() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
System.out.println("start");
KeyStore ks = KeyStore.getInstance("");
ks.load(null, null);
System.out.println("end");
}
}
Test Class
package com.foo.test;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertificateException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.foo.KeyStoreService;
@PrepareForTest(KeyStoreService.class)
@RunWith(PowerMockRunner.class)
public class TestKeyStore {
@Test
public void test1() throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, CertificateException, IOException{
PowerMockito.mockStatic(KeyStore.class);
KeyStore keyStoreMock = PowerMockito.mock(KeyStore.class);
KeyStoreService kss = new KeyStoreService();
PowerMockito.when(KeyStore.getInstance(Matchers.anyString(), Matchers.anyString())).thenReturn(keyStoreMock);
Mockito.doNothing().when(keyStoreMock).load(Mockito.any(InputStream.class), Mockito.any(char[].class));
kss.load();
}
}
标签:powermockito,unit-testing,mockito,powermock,java 来源: https://codeday.me/bug/20191027/1942408.html