How to mock static method that returns final class?

前端 未结 1 1445
Happy的楠姐
Happy的楠姐 2021-01-28 06:09

I want to mock next line:

Bigquery bigquery = Transport.newBigQueryClient(options).build();

The problem here is that newBigQueryClient method r

相关标签:
1条回答
  • 2021-01-28 06:45

    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.

    0 讨论(0)
提交回复
热议问题