First of all, it is a bad practice to make a so-called "partials mocks". This illustrates that your code doesn't follow single responsibility principle that leads to your code being not (or hardly) testable.
I would suggest you to extract getDescription
method from your class and use it indirectly via dependency inversion or more concrete - dependency injection (for instance by employing Spring Framework):
public class TestClass() {
private DetailsServiceProvider detailsServiceProvider;
public TestClass(DetailsServiceProvider detailsServiceProvider) {
this.detailsServiceProvider = detailsServiceProvider;
}
public String getDescription(String input) {
String value = detailsServiceProvider.getDetails(input); // i am not going to change this line, hence want to mock this.
//below this i have some complexity logic, which i would like to fix cyclomatic complexity issue
}
}
public interface DetailsServiceProvider {
String getDetails(String input);
}
public class DetailsServiceProviderImpl implements DetailsServiceProvider{
@Override
public String getDetails(String input) {
return "More details for the "+input;
}
}
Then in your test, you could simply:
@Test
public void test() {
DetailsServiceProvider mockedProvider = Mockito.mock(DetailsServiceProvider.class);
//TODO: add scenarios for the mocked object
TestClass target = new TestClass(mockedProvider);
String description = target.getDescription();
//TODO: add assertions
}
If you do not want to struggle with the preferred approach you could use @Spy in Mockito. This will create exactly what you want - a partial mock for your object where part of the methods will be real and another part - mocks:
@Test
public void test() {
TestClass partialMockedObject = Mockito.spy(new TestClass());
Mockito.doReturn("test details").when(partialMockedObject).getDetails();
String description = partialMockedObject.getDescription();
//TODO: add assertions
}
Again, this method is not desired but can be used if no other options are given. Note that this requires getDetails()
to be visible in tests, meaning that the private
modifier won't work here.