Manthan Jamdagni
Manthan Jamdagni

Reputation: 1031

Test code for getting list of fileNames from s3 bucket from a specific folder

I have this function which gets the List of fileNames from a specific s3 folder from a specific folder bucket which looks like this :

public List<String> listFilesFromS3Bucket(String bucketName, String folderName, String fileNamePrefix) {

    List<String> fileNames = new ArrayList<>();

    String folderPathPrefix = folderName + fileNamePrefix;

    ObjectListing listing = s3Client.listObjects(bucketName, folderPathPrefix);


    List<S3ObjectSummary> s3ObjectSummaries = listing.getObjectSummaries();

    for (ListIterator<S3ObjectSummary> iterator = s3ObjectSummaries.listIterator(); iterator.hasNext();) {

        String keyName = iterator.next().getKey();

        if (!keyName.endsWith("/")) {
            fileNames.add(StringUtils.substringAfterLast(keyName, "/"));
        }
    }

    log.info("Total {} files to process", fileNames.size());
    return fileNames;
}

Now i need to test this piece of code, I have created a mock of s3client and verified call to listObjects. I wan't the test to verify the call to listObjects and which i did by -

Mockito.Verify(s3Client).listObjects(bucketname, prefix);

but how should i test the remaining code, i am pretty new to testing ?

Upvotes: 1

Views: 3324

Answers (3)

Sabir Khan
Sabir Khan

Reputation: 10142

One flaw that I see in your code that you assume , listing to be always non - null. Verify that its always the case since your code assumes that. Similar is the case with - s3ObjectSummaries & keyName references.

If listing is empty , would your code work OK?

Execute a test when !keyName.endsWith("/") is true and another when its false.

How your code behaves for any RuntimeException? How do you want to handle that?

These are just sample things that you would test for your method and that is achieved not by one test method but many test methods i.e. for your one single target method, you would write many many test methods covering all scenarios & code paths and eventually correcting your code ( if you find any flaw ).

Put any code coverage plug in to your IDE ( if your IDE doesn't provide that ) and try to achieve 100% code coverage through all these various test methods.

You shouldn't restrict yourself to a few number of test methods for a target method - you should go on unless you achieve 100% code coverage ( if that is possible ) . You should also be open to changing your code if your unit test results say so.

Mockito when are used to set various data for your various scenarios and verify would be used to check invocations etc on that mock. Few very good samples are listed here

Also, unit tests are not integration tests so in my opinion, you should always write unit tests mocking your s3Client or any such dependencies.

Upvotes: 0

Bgvv1983
Bgvv1983

Reputation: 1256

What I normaly test are 3 things.

1) The output for a given input (usually more then 1 test)

2) Are the correct calls executed on injected objects. e.g. are for a given input the right parameters passed to the method call on that injected object.

3) When it is possible for a method to throw an exception . test if for a given input the right exception is thrown.

Also make sure "all" your paths are covered. Your IDE can help you with this

for your method I would test the following:

1) test if Mockito.Verify(s3Client).listObjects(bucketname, prefix); is executed exactly once. 2) test for multiple inputs the list of output filenames. Use inputs which makes the loop executing 0,1 and multiple times

hope this answers your question

Upvotes: 1

Preston Martin
Preston Martin

Reputation: 2963

Your question is a somewhat broad question, but if I were you, I would test the entire listFilesFromS3Bucket method. This way, you can be certain that your codes properly functions as a unit instead of the functioning of the individual pieces. Once you have done that, then test various expected inputs of your function to validate expected output, error handling, etc. This also will address and separation of concerns in your function that you may need to implement.

Upvotes: 0

Related Questions