I need to mack a class for testing. The problem is i am using third party library where the class(UpdateManager) constructor takes 5 arguments i.e one java.sql.Connection and others are string. Inside that constructor it creates one class instance(DataSource) by passing constructor argument as connection. In that data source instance it calls one of its method which invokes stored procedure. My problem is i created partial mocking of UpdateManager by passing those 5 parameter with mocked connection but inside constructor when in invokes the method on DataSource it throws null pointer exception. Before i stubbed the DataSource by given below
Mockito.doNothing().when(dataSource).update(
Mockito.any(DataSource.class), Mockito.any(ArrayList.class), Mockito.anyInt());
Still its throwing NullPointException as everytime the constructor creates new instance of DataSource. How do i mock it in this scenario without db connection only throwing my stubbed exception or doNothing.I used MOCKITO.Is there any better solution using proxy pattern on this.
Your Suggestion will be appreciated .
Yes, a proxy class is one way to resolve these types of issues with 3rd party classes. You can then simply mock your proxy class instead of the 3rd party classes without implications. The downside to this approach is you end up with these additional wrapper classes just to support your testing.
In this specific case it may be beneficial for you to add a Factory class to act as the proxy, seeing as you're interested in the creation of these UpdateManager
objects
public class UpdateManagerFactory {
public UpdateManager createInstance(... args...) {
return new UpdateManager(... args...);
}
}
If you're using Spring or similar for your dependency injection you can get away with this Factory being a singleton bean in your application context, so need to make it static
. If you do want to make this Factory static you can use powermockito to mock it.
Tip: Don't be afraid to add code in order to make your application easier to test
Edit following your comments
Don't use a spy() for your Factory class, mock it instead
public void myTest() {
Foo classUnderTest = new Foo();
UpdateManagerFactory umf = mock(UpdateManagerFactory.class);
UpdateManager um = mock(UpdateManager.class);
when(umf.createInstance()).thenReturn(um);
// perform test that will call umf.createInstance() at some point
classUnderTest.doSomething();
// verify + assert on "umf" and "um"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With