I want to mock next line:
Bigquery bigquery = Transport.newBigQueryClient(options).build();
The problem here is that newBigQueryClient method returns Bulder class, which is final. This means that I cannot mock it neither with mockito or powermockito(it returns such exception: Cannot subclass final class), but I need to return something suitable to mock build method on it. Any ideas how to do it?
A suggestion to improve your code and making it much more testable:
First of all, you do not mock a statement like the assignment that you gave us as an example. You mock objects and assign their references to variables whose type represent a super type.
Additionally, if you feel you have to mock something away, you have obviously found a dependency in your code snippet that is an important concept.
Make this concept obvious!
In your case, you want to get a Bigquery
object and assign its reference to a variable. The unclear concept is that someone has to provide such an object.
Make this concept clear with an interface:
interface BigqueryProvider {
Bigquery provide(Object options);
}
In your class where you also have the statement
Bigquery bigquery = Transport.newBigQueryClient(options).build();
you now add the following instance variable
private final BigqueryProvider bigqueryProvider;
and change your constructors accordingly. As I made it final
it must be set at construction time. Of course, you must also identify the code where you call the constructors. For that you also need a default implementation:
final class DefaultBigqueryProvider implements BigqueryProvider {
@Override
public Bigquery provide(Object options) {
return Transport.newBigQueryClient(options).build();
}
}
Then change the above mentioned assignment to
Bigquery bigquery = bigqueryProvider.provide(options);
Now to the tests: In your tests, you now can provide a test implementation for the provider interface. A mocking framework can easily do that for you. You are also able to return a Bigquery
object of your choice, being it an object of that class or of a subclass, it doesn't matter.
Your test code then instantiates your class by providing them a mocked BigqueryProvider
which you have under full control.