Test class with a new() call in it with Mockito

bwobbones picture bwobbones · May 7, 2011 · Viewed 156.2k times · Source

I have a legacy class that contains a new() call to instantiate a LoginContext():

public class TestedClass {
  public LoginContext login(String user, String password) {
    LoginContext lc = new LoginContext("login", callbackHandler);
  }
}

I want to test this class using Mockito to mock the LoginContext as it requires that the JAAS security stuff be set up before instantiating but I'm not sure how to do that without changing the login() method to externalize the LoginContext. Is it possible using Mockito to mock the LoginContext class?

Answer

Tomasz Nurkiewicz picture Tomasz Nurkiewicz · May 7, 2011

For the future I would recommend Eran Harel's answer (refactoring moving new to factory that can be mocked). But if you don't want to change the original source code, use very handy and unique feature: spies. From the documentation:

You can create spies of real objects. When you use the spy then the real methods are called (unless a method was stubbed).

Real spies should be used carefully and occasionally, for example when dealing with legacy code.

In your case you should write:

TestedClass tc = spy(new TestedClass());
LoginContext lcMock = mock(LoginContext.class);
when(tc.login(anyString(), anyString())).thenReturn(lcMock);