Reputation: 7604
I have an interface
public interface Example{
public int sum(int a, int b);
public int diff(int a, int b);
}
Now I have an implementation for this Interface:
public RealMath implements Example{
public int sum(int a, int b){
//contact server do stuff and return value.
return val;
}
public int diff(int a, int b){
//contact server do stuff and return value.
return val;
}
}
And there is a factory to provide the respective implementation:
public class ExampleFactory(){
public static final Example getExampleIns(String val){
return new RealMath();
}
}
Now, I have a class User.java
which uses this Example
Interface for some work.
I want to test User
in which there is a method which calls:
Example ex = ExampleFactory.getExampleIns();
ex.sum(val1, val2);
And based on this value it does some processing.
I want to unit test my code and would like to have a mocked implementation of Example interface, so that server dependency is not required and I just return some mocked values for the methods in the interface.
My thought is to provide my mocked implementation when ExampleFactory.getExampleIns();
is called (when the test case is running).
I tired Mockito (Android) and that does not support static method mocking.
So I have two questions: 1. What is wrong with the above design where I have a factory and various implementations and return the suitable object based on requirements?
User.java
by providing my mocked implementation for Example
interface?Thanks.
Upvotes: 0
Views: 76
Reputation: 4056
- What is wrong with the above design where I have a factory and various implementations and return the suitable object based on requirements?
The implementation that you deliver in the factory is hardcoded, so, if you want to change the implementation, you have to change the code. You have no way to dynamically change the impl.
2.- How do I test User.java by providing my mocked implementation for Example interface?
Instead of using a factory, use Dependency Injection. You can pass the proper implementation of Example
to your User
in the constructor (for example), and store it as an instance variable, so that you can use it afterwards:
private Example exampleImpl;
public User(Example exampleImpl) {
this.exampleImpl = exampleImpl;
}
public void methodUsingExample(Integer val1, Integer val2) {
exampleImpl.sum(val1, val2);
}
When testing, you construct your User
instance with the Example
mock:
Example mockExample = mock(Example.class);
User user = new User(mockExample);
// now User is using your mock
user.methodUsingExample(1, 2);
Upvotes: 1