这是我从myClient类测试的方法:
public FSDataInputStream getObj(String hName, Path p) throws IOException {
if (p.toString().contains("?tkn=")) {
checkToken(p);
p = new Path(removeTkn(p.toString()));
}
String myKey = pathToKey(hName, p);
FileStatus status = memoryCache.getStatus(p.toString());
if (status == null) {
status = getStatus(hName, p, "getObj");
}
if (status.isDirectory()) {
throw new FileNotFoundException("Can't open " + path
+ " because it is a directory");
}
InputStream inputStream = new InputStream(bucket, myKey,
status.getLen(), client, readAhead, inputPolicy);
return new FSDataInputStream(inputStream);
}
如果fileStatus是方法中的目录,则此JUnit测试检查是否引发了异常:
@Test
public void getDirectoryObjectTest() throws Exception {
String host = "file://abc.def";
Path p = new Path("file://abc.def/123.txt");
when(memoryCache.getStatus(p.toString())).thenReturn(fileStatus);
when(fileStatus.isDirectory()).thenReturn(true);
exception.expect(FileNotFoundException.class);
myClient.getObj(host, p);
}
它按预期工作。
我现在希望使用路径file://abc.def/123.txt?tkn=xyz
进行相同的测试。如果我只是这样做:
@Test
public void getDirectoryObjectTest2() throws Exception {
String host = "file://abc.def";
Path p = new Path("file://abc.def/123.txt?tkn=xyz");
when(memoryCache.getStatus(p.toString())).thenReturn(fileStatus);
when(fileStatus.isDirectory()).thenReturn(true);
exception.expect(FileNotFoundException.class);
myClient.getObj(host, p);
}
我收到以下错误:
org.apache.http.conn.ssl.SSLInitializationException:为SSLContext配置的类:sun.security.ssl.SSLContextImpl $ TLSContext不是SSLContext 在com.amazonaws.internal.SdkSSLContext.getPreferredSSLContext(SdkSSLContext.java:37) at com.amazonaws.http.apache.client.impl.ApacheConnectionManagerFactory.getPreferredSocketFactory(ApacheConnectionManagerFactory.java:91) 在com.amazonaws.http.apache.client.impl.ApacheConnectionManagerFactory.create(ApacheConnectionManagerFactory.java:65) 在com.amazonaws.http.apache.client.impl.ApacheConnectionManagerFactory.create(ApacheConnectionManagerFactory.java:58) 在com.amazonaws.http.apache.client.impl.ApacheHttpClientFactory.create(ApacheHttpClientFactory.java:50) ....
checkToken()
是一个私有的void方法,用于创建AmazonS3客户端。出于本次测试的目的,我并不关心它。有什么方法可以创建某种允许测试运行的模拟吗?
修改
添加checkToken()
private void checkToken(Path p) {
String tkn = Utils.extractTkn(p);
customTkn = new CustomTokenManager(tkn);
creds = new BasicOAuthCredentials(customTkn, serviceInstanceID);
cConf = new ClientConfiguration();
credProvider = new AWSStaticCredentialsProvider(creds);
clientBuilder = AmazonS3ClientBuilder.standard()
.withClientConfiguration(cConf)
.withPathStyleAccessEnabled(true)
.withCredentials(cProvider);
if (serviceUrl != null && !serviceUrl.equals(amazonDefaultEndpoint)) {
EndpointConfiguration endpoint = new EndpointConfiguration(serviceUrl,
Regions.DEFAULT_REGION.getName());
clientBuilder.withEndpointConfiguration(endpoint);
} else {
clientBuilder.withRegion(Regions.DEFAULT_REGION);
}
myClient = clientBuilder.build();
}
更新
我已尝试过这个但显然不正确。我不确定自己有多么不对劲。我甚至走在正确的道路上吗?
我为AmazonS3ClientBuilder
,ClientConfiguration
和AWSStaticCredentialsProvider
创建了模拟效果:
@Mock
AmazonS3ClientBuilder mClientBuilder;
@Mock
ClientConfiguration mClientConf;
@Mock
AWSStaticCredentialsProvider mCredsProvider;
然后我修改了我的测试如下:
@Test
public void getDirectoryObjectTest2() throws Exception {
String host = "file://abc.def";
Path p = new Path("file://abc.def/123.txt?tkn=xyz");
when(memoryCache.getStatus(p.toString())).thenReturn(fileStatus);
when(fileStatus.isDirectory()).thenReturn(true);
when(AmazonS3ClientBuilder.standard()
.withClientConfiguration(mClientConf)
.withPathStyleAccessEnabled(true)
.withCredentials(mCredsProvider)).thenReturn(mClientBuilder);
exception.expect(FileNotFoundException.class);
myClient.getObj(host, p);
}
我认为这部分工作的部分原因是因为虽然我已经制作了嘲讽,但它们实际上并没有任何价值。
另外,当我运行测试时,我得到了这个:
java.lang.RuntimeException:在PowerMock测试侦听器org.powermock.api.extension.listener.AnnotationEnabler@333d4a8c上调用beforeTestMethod方法失败。 at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:92) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:292) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.access $ 100(PowerMockJUnit47RunnerDelegateImpl.java:59) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner $ LastRuleTestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:148) at org.junit.rules.ExpectedException $ ExpectedExceptionStatement.evaluate(ExpectedException.java:239) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:91) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) 在org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87) 在org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ 1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) 在org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) 在org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122) 在org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106) 在org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) 在org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59) 在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 在org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 引起:java.lang.IllegalArgumentException:不能继承最终类类com.amazonaws.services.s3.AmazonS3ClientBuilder 在org.mockito.cglib.proxy.Enhancer.generateClass(Enhancer.java:447) 在org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) 在org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217) 在org.mockito.cglib.proxy.Enhancer.createHelper(Enhancer.java:378) 在org.mockito.cglib.proxy.Enhancer.createClass(Enhancer.java:318) 在org.powermock.api.mockito.repackaged.ClassImposterizer.createProxyClass(ClassImposterizer.java:123) 在org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:57) 在org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:110) 在org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:58) 在org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:203) at org.powermock.api.extension.listener.AnnotationEnabler.standardInject(AnnotationEnabler.java:106) at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:54) at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:90) ......还有24个
当我仅添加以下内容并运行getDirectoryObjectTest2()
的原始版本时,上述错误实际上已被抛出,因此可能还有其他一些问题:
@Mock
AmazonS3ClientBuilder mClientBuilder;
这是对的吗?
UPDATE2
我在AmazonS3ClientBuilder
注释中添加了@PrepareForTest
。
@PrepareForTest({ObjectMetadata.class, COSInputPolicy.class, AmazonS3ClientBuilder.class})
现在我收到了这个错误:
org.mockito.exceptions.misusing.MissingMethodInvocationException: when()需要一个参数,该参数必须是模拟'上的方法调用。 例如: 当(mock.getArticles())thenReturn(文章);
此外,此错误可能会显示,因为: 1.你存在以下任何一个:final / private / equals()/ hashCode()方法。 这些方法无法进行存根/验证。 不支持在非公共父类上声明的模拟方法。 2.在()内部,你不会在模拟上调用方法,而是在其他对象上调用方法。
at com.ibm.stocator.fs.cos.unittests.COSAPIClientTest.getDirectoryObjectWithTokenInPathTest(COSAPIClientTest.java:263) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) 在org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310) 在org.junit.internal.runners.MethodRoadie $ 2.run(MethodRoadie.java:89) 在org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.access $ 100(PowerMockJUnit47RunnerDelegateImpl.java:59) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner $ LastRuleTestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:148) at org.junit.rules.ExpectedException $ ExpectedExceptionStatement.evaluate(ExpectedException.java:239) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:91) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) 在org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87) 在org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ 1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) 在org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) 在org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) 在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122) 在org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106) 在org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) 在org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59) 在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 在org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
这纯粹是因为checkToken()是私有的还是我做错了什么?