Mocking Internal Objects in a Clean Way

Mocking Internal Objects in a Clean Way

/ Olivier Dugas

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:

public class User {
    private String name;
    private Authenticator authenticator;

You could have a constructor that looks like this:

    public User(String 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:

protected User(String name, Authenticator authenticator) { = 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:

  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.

    class UserMock extends User { 
        public UserMock(String name, Authenticator authenticator) {
        super(name, authenticator);

I hope this will help!