Java 为JUnit测试模拟对象

Java 为JUnit测试模拟对象,java,unit-testing,junit,mocking,mockito,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

我正在编写一个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新手,所以不完全确定我在做什么,但就我所知,我认为我需要嘲笑以下几点:

  • 列表项
  • 客户
  • 地位
  • 输入流
  • 可能是记忆卡
  • 到目前为止,我得到的是:

    @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());
    
    我想知道是否有人能建议我是否/我正在做什么,以及我应该如何着手解决这个问题?

    首先,真正的答案是:退后一步。不要以JUnit和Mockito以及您的生产代码作为输入。而是看一看教程(比如)一步一步地解释所有相关元素以及如何将它们“组合”在一起

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

    • 为什么要使用PowerMock?试着搭配“纯香草”摩基托。如果您的生产代码是需要PowerMock的,那么应该考虑修改您的生产,而不是转向PrimeCK。
    • 你似乎真的不知道在哪里/如何使用嘲弄。换句话说:在运行测试代码时,您只需模拟需要控制的元素。如果你不能控制他们,你只能使用嘲弄。意思:你几乎从不模仿一个列表——你只需要创建一个“普通”列表,然后添加这个列表应该包含的内容
    • 创建模拟允许调用该模拟对象上的方法。但在默认情况下,任何返回内容的方法都将返回null(或者可能是空集合,或者0表示基本返回类型,请参阅以了解详细信息)。因此,您需要一个语句,例如
      when(mockedCache.getStatus(“some string”))。然后返回(someResult)

    带有3个。状态你的意思是
    getStatus()
    ?什么是
    memoryCache
    ?它是如何初始化/注入到您的类中的?您在什么地方调用类中的
    getObj
    。Sergii Bishyr-我不确定你在问什么,但我相信我所做的是错误的。很好的解释。第三点不太正确。mock上方法的默认返回值取决于其返回类型-它并不总是返回null。有许多难以记忆的异常,如下所示。返回
    集合的方法将返回空,默认情况下不为null。返回基元类型的方法将返回0或false。返回原语包装类型的方法也将返回0或false。标准的
    compareTo
    方法默认为1,标准的
    toString
    方法默认为模拟的名称。谢谢GhostCat。我会查清楚的。@DawoodibnKareem谢谢。我不知道-我相应地更新了答案。谢谢@GhostCat。我必须在这方面做一点工作,但这很有帮助。