使用Mockito通过new()调用测试类

我有一个旧类,其中包含用于实例化LoginContext()的new()调用:


public class TestedClass {

  public LoginContext login(String user, String password) {

    LoginContext lc = new LoginContext("login", callbackHandler);

  }

}

我想使用Mockito测试类来模拟LoginContext,因为它要求在实例化之前设置JAAS安全性,但是我不确定如何在不更改login()方法以外部化LoginContext的情况下进行此操作。是否可以使用Mockito模拟LoginContext类?


料青山看我应如是
浏览 1126回答 3
3回答

30秒到达战场

对于将来,我会推荐伊兰·哈雷尔(Eran Harel)的答案(将new工厂搬迁到可以嘲笑的工厂)。但是,如果您不想更改原始源代码,请使用非常方便且独特的功能:spies。从文档中:您可以创建真实对象的间谍。当您使用间谍时,将调用实际方法(除非对方法进行了加注)。真正的间谍应该小心谨慎地使用,例如在处理遗留代码时。在您的情况下,您应该写:TestedClass tc = spy(new TestedClass());LoginContext lcMock = mock(LoginContext.class);when(tc.login(anyString(), anyString())).thenReturn(lcMock);

www说

我全力支持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();    }}...这是旧代码,无法重构以提取新的初始化LoginContext为其自己的方法并应用上述解决方案之一。为了完整起见,值得一提的是第三种技术- 在调用运算符时使用PowerMock注入模拟对象new。但是,PowerMock并不是灵丹妙药。它通过在其模拟的类上应用字节码操作来工作,如果所测试的类采用字节码操作或反射,并且至少从我的个人经验出发,已知该类会给测试带来性能损失,那么这可能是狡猾的实践。再说一次,如果没有其他选择,则唯一的选择必须是好的选择:@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    }}

守着星空守着你

您可以使用工厂来创建登录上下文。然后,您可以模拟工厂并返回您想要进行测试的任何内容。public class TestedClass {  private final LoginContextFactory loginContextFactory;  public TestedClass(final LoginContextFactory loginContextFactory) {    this.loginContextFactory = loginContextFactory;  }  public LoginContext login(String user, String password) {    LoginContext lc = loginContextFactory.createLoginContext();  }}public interface LoginContextFactory {  public LoginContext createLoginContext();}
打开App,查看更多内容
随时随地看视频慕课网APP