Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppot mocking of s3ClientConfiguration to build S3TransferManager for unit test Java #2898

Closed
balajikarthickkbk opened this issue Dec 8, 2021 · 8 comments
Labels
closed-for-staleness guidance Question that needs advice or information. transfer-manager

Comments

@balajikarthickkbk
Copy link

balajikarthickkbk commented Dec 8, 2021

Describe the issue

am using java aws sdk v2 S3TransferManager to upload files to s3.

At the moment am mocking s3ClientConfiguration using mockito 2.0 as below,

`
S3ClientConfiguration s3ClientConfiguration =mock(S3ClientConfiguration.class);

   s3TransferManager = S3TransferManager.builder().s3ClientConfiguration(s3ClientConfiguration).build();

`

which throws me the error,

**java.util.concurrent.CompletionException: software.amazon.awssdk.services.s3.model.S3Exception: Invalid response status from request**

This is my actual code which contains the method transferobject for which am writing the unit test,
image

and this is my unit test code,

image

and this is my exception,
image

so what is the solution to figure out what the root cause is? or what is the right way to mock "S3ClientConfiguration" for unit test in java using aws sak v2.

Help is appreciated. Thank you.

Steps to Reproduce

See snippet above

Current behavior

unit test fails due to the exception, ava.util.concurrent.CompletionException: software.amazon.awssdk.services.s3.model.S3Exception: Invalid response status from request

AWS Java SDK version used

V2

JDK version used

1.8

Operating System and version

Windows

@balajikarthickkbk balajikarthickkbk added guidance Question that needs advice or information. needs-triage This issue or PR still needs to be triaged. labels Dec 8, 2021
@zoewangg
Copy link
Contributor

zoewangg commented Dec 8, 2021

Hi @balajikarthickkbk, currently it's not supported to swap out the underlying S3 client used by the transfer manager, so it looks like your test is actually sending requests to S3. Marking this as a feature request. Would mocking S3TransferManager work in your use-case?

@zoewangg zoewangg added transfer-manager feature-request A feature should be added or improved. and removed needs-triage This issue or PR still needs to be triaged. guidance Question that needs advice or information. labels Dec 8, 2021
@balajikarthickkbk
Copy link
Author

balajikarthickkbk commented Dec 8, 2021

have also tried mocking s3Transfermanager but it returns only Nullpointerexception,

unit tes tcode where I have mocked S3TransferManager,

image

the Null Pointer Exception in actual code when I mock S3TransferManager,

image
image

so if mocking of S3ClientConfiguration is not supported now, how could we unit test S3TransferManager upload functionality,
is that we need to unit test against actual S3-bucket by passing the actual credentials in unit test and not a mocked one?

@balajikarthickkbk
Copy link
Author

balajikarthickkbk commented Dec 8, 2021

Hi @zoewangg any update on my previous question?

so if mocking of S3ClientConfiguration is not supported now, how could we unit test S3TransferManager upload functionality,
is that we need to unit test against actual S3-bucket by passing the actual credentials in unit test and not a mocked one?

@zoewangg
Copy link
Contributor

zoewangg commented Dec 8, 2021

I believe you would need to mock the response of the S3TransferManager#uploadFile, see sample code below.

        S3TransferManager s3TransferManager = Mockito.mock(S3TransferManager.class);
        FileUpload fileUpload = Mockito.mock(FileUpload.class);
        UploadFileRequest uploadRequest = UploadFileRequest.builder()
                                                           .putObjectRequest(PutObjectRequest.builder().bucket("bucket").key(
                                                               "key").build())
                                                           .source(Paths.get("."))
                                                           .build();
        Mockito.when(s3TransferManager.uploadFile(uploadRequest)).thenReturn(fileUpload);

@zoewangg zoewangg added guidance Question that needs advice or information. and removed feature-request A feature should be added or improved. labels Dec 8, 2021
@balajikarthickkbk
Copy link
Author

Thanks @zoewangg this helps in testing the upload functionality of S3TransferManager, However the actual method which am testing returns null when I mock S3TransferManager,

my actual method,

image

test code,

image

@zoewangg
Copy link
Contributor

zoewangg commented Dec 8, 2021

It seems the UploadRequest mocked in the Mokito.when(s3TrasnferManager.upload(uploadRequest)).thenReturn(fileUpload) is not the same as the actual UploadRequest being used.

Could you make sure the request parameters are the same?

@balajikarthickkbk
Copy link
Author

balajikarthickkbk commented Dec 8, 2021

have made both the UploadRequest mocked in the Mokito.when(s3TrasnferManager.upload(uploadRequest)).thenReturn(fileUpload) and actual UploadRequest being used parameters as same now,

image

but still null pointer exception occurs in this line, CompletedUpload completedUpload = upload.completionFuture().join(); in my actual method as seen below,

image

any final advice on this?

my actual code block,

``public void transferObject(UploadRequest uploadRequest) {

	try {
		Upload upload =
				s3TransferManager.upload(uploadRequest);
		CompletedUpload completedUpload = upload.completionFuture().join();

		log.info("PutObjectResponse: " + completedUpload.response());
	} catch (CompletionException e) {
		e.printStackTrace();
	}


}

my unit test code,

`@Test
public void transferObject_singleFile_ShouldUploadFiletoS3() throws IOException {

	Upload fileUpload = Mockito.mock(Upload.class);
	String fileName = FILE_PATH + UPLOAD_FILE_NAME;
	writeFile(fileName);
	String s3Key = VALID_S3_KEY_UPLOAD + UPLOAD_FILE_NAME;
	UploadRequest uploadRequest = UploadRequest.builder()
			.putObjectRequest(PutObjectRequest.builder().bucket("bucket").key(
					"key").build())
			.source(Paths.get("."))
			.build();
	Mockito.when(s3TransferManager.upload(uploadRequest)).thenReturn(fileUpload);
	service.transferObject(uploadRequest);
	int expectedObjectsSize = 1;
	Log.initLoggingToFile(Log.LogLevel.Error, "log.txt");
	List<S3Object> matchedObjects = awsS3Service.listObjectsWithPrefix(s3Key);
	assertEquals(expectedObjectsSize, matchedObjects.size());
	assertEquals(s3Key, matchedObjects.get(0).key());
}`

@zoewangg
Copy link
Contributor

zoewangg commented Dec 8, 2021

Yeah, I think you would need to mock the response of Upload#completionFuture as well. Basically, you need to write the expected behavior for the method that returns for the mocked object because unstubbed methods return null by default You can find more information on the official mockito site https://javadoc.io/doc/org.mockito/mockito-core/2.28.2/org/mockito/Mockito.html

@zoewangg zoewangg added the closing-soon This issue will close in 4 days unless further comments are made. label Dec 15, 2021
@github-actions github-actions bot added closed-for-staleness and removed closing-soon This issue will close in 4 days unless further comments are made. labels Dec 15, 2021
aws-sdk-java-automation added a commit that referenced this issue Feb 12, 2024
…94ef52b8e

Pull request: release <- staging/baeb5fd3-6689-4694-ba51-04c94ef52b8e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-for-staleness guidance Question that needs advice or information. transfer-manager
Projects
None yet
Development

No branches or pull requests

2 participants