JUnit - 导致测试失败的私有方法

时间:2018-01-22 07:33:02

标签: java junit mockito junit4

这是我从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();

}

更新

我已尝试过这个但显然不正确。我不确定自己有多么不对劲。我甚至走在正确的道路上吗?

我为AmazonS3ClientBuilderClientConfigurationAWSStaticCredentialsProvider创建了模拟效果:

@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()是私有的还是我做错了什么?

0 个答案:

没有答案