Void’s Vault

Knowledge source for efficiency.

Mocking Internal Objects in a Clean Way

Suppose you have a class with a public constructor. This class contains a private object that do a lot of stuff you don’t want it to do for unit testing. Here’s an excellent way to do that.

Imagine you have a User class that contains a class for authentication:

1
2
3
public class User {
    private String name;
    private Authenticator authenticator;

You could have a constructor that looks like this:

1
2
3
4
public User(String name) {
this.name = name;
authenticator = new Authenticator(name);
}

Uh-oh! How can we stop user from using Authenticator class so we can make real unit tests? I’ve searched a lot, but in the end, I believe the best way to do this is to add a little bit of code pollution. You have to add a protected constructior like this:

1
2
3
4
protected User(String name, Authenticator authenticator) {
this.name = name;
this.authenticator = authenticator;
}

And you are done! Just add a little comment mentionning that this constructor is only to be used for unit testing purposes, and the tests will go straight forward with JUnit and Mockito:

1
2
3
4
5
6
@Before
  public void setup() {
    authenticator = mock(Authenticator.class);
    when(authenticator.getUID()).thenReturn("Mocked Name!");
    user = new UserMock("A user Name", authenticator);
  }

Notice the UserMock thing. No, it’s not a User, you are right! We use the protected constructor to extend User in our UserTest file.

1
2
3
4
5
class UserMock extends User {
    public UserMock(String name, Authenticator authenticator) {
    super(name, authenticator);
}
}

I hope this will help!