为了账号安全,请及时绑定邮箱和手机立即绑定

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

使用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类?
查看完整描述

3 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

对于将来,我会推荐伊兰·哈雷尔(Eran Harel)的答案(将new工厂搬迁到可以嘲笑的工厂)。但是,如果您不想更改原始源代码,请使用非常方便且独特的功能:spies。从文档中:


您可以创建真实对象的间谍。当您使用间谍时,将调用实际方法(除非对方法进行了加注)。


真正的间谍应该小心谨慎地使用,例如在处理遗留代码时。


在您的情况下,您应该写:


TestedClass tc = spy(new TestedClass());

LoginContext lcMock = mock(LoginContext.class);

when(tc.login(anyString(), anyString())).thenReturn(lcMock);


查看完整回答
反对 回复 2019-10-29
?
www说

TA贡献1775条经验 获得超8个赞

我全力支持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

    }

}


查看完整回答
反对 回复 2019-10-29
?
守着星空守着你

TA贡献1799条经验 获得超8个赞

您可以使用工厂来创建登录上下文。然后,您可以模拟工厂并返回您想要进行测试的任何内容。


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();

}


查看完整回答
反对 回复 2019-10-29
  • 3 回答
  • 0 关注
  • 1111 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信