模拟JUnit测试的对象

时间:2018-01-15 08:22:35

标签: java unit-testing junit mocking mockito

我正在写一个Junit来测试Client.java中的以下方法:

public FSDataInputStream getObj(String hName, Path p) throws IOException {

    String myKey = pathToKey(hName, p);
    FileStatus status = memoryCache.getStatus(p.toString());
    if (status == null) {
      status = getStatus(hName, p, "getObject");
    }
    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);
}

最初我想测试status == null然后调用getStatus(),如果status.isDirectory(),则抛出FileNotFoundException

我是Junit的新手所以不完全确定我在做什么,但据我所知,我认为我需要嘲笑以下内容:

  1. 列表项
  2. 客户端
  3. 状态
  4. 的inputStream
  5. 可能是memoryCache
  6. 到目前为止,这就是我所拥有的:

    @Before
    public final void before() {
        private COSAPIClient myClient;
        private String myBucket;
        FileStatus myStatus;
        InputStream myInputStream;
    
        myClient = PowerMockito.mock(AmazonS3.class);
        myInputStream = PowerMockito.mock(InputStream.class);
        myFileStatus = PowerMockito.mock(FileStatus.class);
    }
    
    @Test
    public void getObjTest() throws Exception {
        URI uri = new URI("xyz://aa-bb-cc/data7-1-23-a.txt");
        String hName = "xyz://aa-bb-cc/";
        Path p = new Path("cos://aa-bb-cc/data7-1-23-a.txt");
    
        Configuration conf = new Configuration();
    
        myClient = spy(new Client(uri, conf));
        myStatus = spy(new FileStatus());
        myMemoryCache.getStatus(p.toString());
    
        InputStream = spy(new InputStream(myBucket, objectKey, 300, myClient, 12345678910L, myInputPolicy));
    }
    

    它在我的程序中的这一行返回一个NullPointerError:

    FileStatus status = memoryCache.getStatus(p.toString());
    

    我想知道是否有人可以建议我/我正在做什么wronfg以及我应该如何解决这个问题?

1 个答案:

答案 0 :(得分:7)

首先,真正的答案:退一步。不要以JUnit和Mockito以及您的生产代码作为输入开始。而是深入研究一个教程(如here),逐步解释所有相关元素以及如何将它们“结合”在一起。

在您的情况下,您的代码存在各种问题:

  • 你为什么使用PowerMock?尝试使用“普通香草”Mockito。如果您的生产代码需要PowerMock,那么请考虑重新设计生产而不是转向PowerMock。
  • 你似乎真的不知道在哪里/如何应用嘲笑。换句话说:在运行代码的代码时,模拟控制所需的元素。如果你不能控制它们,你只能使用模拟。含义:您几乎从不模拟列表 - 您只需创建一个“普通”列表,然后添加此列表应包含的内容。
  • 创建模拟允许调用该模拟对象上的方法。但是默认情况下,任何返回内容的方法都将返回null(或者可能是空集合,或者对于原始返回类型为0,有关详细信息,请参阅here)。因此,您需要一个诸如when(mockedCache.getStatus("some string")).thenReturn(someResult)
  • 之类的陈述