Introduction

While writing JUnit test cases, we encounter cases like we want to initialize a class, and that class instantiate a new class object which is an external entity class like FTP class or AWS service class. We do not want to initializethat external class object. In that cases, we would want to mock those objects.

Problem

We can mock any object in JUnit test code. But, what about the objects that are instantiated using new inside that class.

Example

class AmazonS3ServiceImpl {
	private AmazonS3Client amazonS3Client;

	public AmazonS3ServiceImpl() {
		this.amazonS3Client = new AmazonS3Client();
	}
}

Here, we would want to inject our mock object for AmazonS3Client, but how?

Solution

You need to annotate your JUnit test class with “@PrepareForTest” and mention both the classes you want to mock. See below:

@RunWith(PowerMockRunner.class)
@PrepareForTest({AmazonS3Client.class, AmazonS3ServiceImpl.class})
public class S3Test {
	@Before 
	public void setup() throws Exception {
		AmazonS3Client amazonS3Client = PowerMockito.mock(AmazonS3Client.class);
		PowerMockito.whenNew(AmazonS3Client.class).withParameterTypes(AWSCredentials.class).
			withArguments(Mockito.any()).thenReturn(amazonS3Client); //code for mocking Impl class
	}
}

Conclusion

So, we have informed Mocking system that whenever you are trying to instantiate a new object of AmazonS3Client class with AWSCredentials type parameter, return our mock object.