Sunny
Sunny

Reputation: 7604

Android: Providing a mocked implementation during testing of a class using an interface

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?

  1. How do I test User.java by providing my mocked implementation for Example interface?

Thanks.

Upvotes: 0

Views: 76

Answers (1)

Ruben
Ruben

Reputation: 4056

  1. 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

Related Questions