I have the following class which has an object 'client' which is initialized by a static method. I do not want to use Powermock and let it get initialized by this static method. I am looking to use mockito to mock the this call => client.rxQueryWithParams().
Is this possible? Tried with the mock up as follows but I still enter the client.rxQueryWithParams() call thus the mockup is not taking effect.
This would have mocked fine it I had just Autowired the SQLClient instead in a framework like Spring. Unable to achieve this in a normal class as follows. If relevant, I am ok to mock that PostgreSQLClient.createShared() call but it doesn't seem to be achievable via mockito and not looking to introduce Powermock as mentioned. Is there a way around this? Thanks.
public class MainClass{
private final SQLClient client;
public MainClass(Vertx vertx, JsonObject config) {
client = PostgreSQLClient.createShared(vertx, getData(config));
}
Single<ResultSet> insert(AddEventRequest request) {
// some logic
return client.rxQueryWithParams(query, new JsonArray(params)); // I want to mock out this call.
}
}
Test
@ExtendWith(MockitoExtension.class)
public class MainClassTest {
private TestSubscriber<Response> subscriber;
private JsonObject configuration;
private MainClass event;
@Mock
private SQLClient client;
@BeforeEach
public void init() {
configuration = SomeStaticMethod.load();
event = new MainClass(Vertx.vertx(), configuration);
subscriber = new TestSubscriber<>();
}
@Test
public void test() {
Request request = getRequest(); // just a method creating an object with some values
// this mock doesn't have any effect
when(client.rxQueryWithParams(anyString(), any(JsonArray.class))).thenThrow(new RuntimeException());
event.addEvent(request).subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
}
}
It is impossible without PowerMock or similar tool.
Mocking static methods is available since Mockito 3.4.
See pull request: Mockito #1013: Defines and implements API for static mocking.
Please note that the fact that this feature is available is not equivalent with recommendation to use it. It is aimed at legacy apps where you cannot refactor the source code.
You will be better off refactoring your MainClass to accept an SQLClient argument in a constructor. You can add an additional, delegating constructor if you need to minimize the impact on your code.
Having said that:
try (MockedStatic<PostgreSQLClient> postgreSQLClientStatic = Mockito.mockStatic(PostgreSQLClient.class)) {
postgreSQLClientStatic.when(() -> PostgreSQLClient.createShared(any(), any())).thenReturn(client);
// NOTE: I create the event when mocked PostgreSQLClient is in scope
MainClass event = new MainClass(Vertx.vertx(), configuration);
when(client.rxQueryWithParams(anyString(), any()))
.thenThrow(new RuntimeException("exception from mock"));
event.insert(request);
}
You can inject the mock instance into MainClass instance via ReflectionTestUtils packaged under org.springframework.test.util
ReflectionTestUtils.setField(event , "client", client);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.