简体   繁体   中英

Mocking objects for JUnit test

I'm writing a Junit to test the following method in 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);
}

Initially I want to test if status == null then getStatus() is invoked and if status.isDirectory() , the FileNotFoundException is thrown

I'm new to Junit so not completely sure what I'm at but to the best of my knowledge I think I need to mock the following:

  1. List item
  2. Client
  3. status
  4. inputStream
  5. possibly memoryCache

So far this is what I've got:

@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));
}

It returns a NullPointerError at this line in my program:

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

I wonder is anybody could advice if/what I'm doing wronfg and how I should go about resolving this?

First, the real answer: step back for a moment. Don't start with JUnit and Mockito and your production code as input. Rather have a look into a tutorial (like here ) that step-by-step explains all the relevant elements and how to "bring" them together.

In your case, the are various problems with your code:

  • Why are you using PowerMock? Try to go with "plain vanilla" Mockito. If your production code is so that it requires PowerMock, rather consider to rework your production instead of turning to PowerMock.
  • You seem to really not know where/how to apply mocking. In other words: you only mock the elements that you need to control when running your code under test . And you only use mocking, if you can't control them otherwise. Meaning: you almost never mock a list - you simply create a "normal" list to then add the things that this list should contain.
  • Creating a mock allows to invoke methods on that mock object. But by default, any method that returns something will return null (or maybe an empty collection, or 0 for primitive return types, see here for details). Thus you rather need a statement such as when(mockedCache.getStatus("some string")).thenReturn(someResult) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM