我完全支持Eran Harel的解决方案,在不可能的情况下,Tomasz Nurkiewicz的间谍建议非常好。但是,值得注意的是,在某些情况下,两者都不适用。例如,如果方法有点“更强”:login
public class TestedClass {
public LoginContext login(String user, String password) {
LoginContext lc = new LoginContext("login", callbackHandler);
lc.doThis();
lc.doThat();
return lc;
}
}
...这是旧代码,无法重构以提取新代码的初始化到自己的方法并应用上述解决方案之一。LoginContext
为了完整性的缘故,值得一提的第三种技术 - 在调用运算符时使用PowerMock注入模拟对象。不过,PowerMock并不是一颗银弹。它的工作原理是对它模拟的类应用字节码操作,如果测试的类使用字节代码操作或反射,这可能是狡猾的做法,至少从我个人的经验来看,已知会在测试中引入性能影响。再说一遍,如果没有其他选项,则唯一的选项必须是好选项:new
@RunWith(PowerMockRunner.class)
@PrepareForTest(TestedClass.class)
public class TestedClassTest {
@Test
public void testLogin() {
LoginContext lcMock = mock(LoginContext.class);
whenNew(LoginContext.class).withArguments(anyString(), anyString()).thenReturn(lcMock);
TestedClass tc = new TestedClass();
tc.login ("something", "something else");
// test the login's logic
}
}