当前位置: 首页 > 知识库问答 >
问题:

用Mockito测试类,其中包含一个新的()调用

朱兴运
2023-03-14

我有一个遗留类,它包含一个new()调用来实例化LoginContext():

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

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

共有3个答案

田俊爽
2023-03-14

您可以使用工厂来创建登录上下文。然后你可以嘲弄工厂并返回任何你想要的测试。

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();
}
微生新霁
2023-03-14

我完全支持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的初始化提取到它自己的方法并应用上述解决方案之一。

为了完整起见,值得一提的是第三种技术--在调用new运算符时使用PowerMock注入mock对象。不过,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
    }
}
狄阳秋
2023-03-14

对于未来,我将推荐EranHarel的答案(重构,将new移动到工厂,可以模仿)。但是如果你不想改变原来的源代码,使用非常得心应手和独特的功能:间谍。从文档中:

你可以创造真实物体的间谍。当您使用spy时,将调用真正的方法(除非某个方法被替换)。

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

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

TestedClass tc = spy(new TestedClass());
LoginContext lcMock = mock(LoginContext.class);
when(tc.login(anyString(), anyString())).thenReturn(lcMock);
 类似资料:
  • 我正在尝试测试,只有在调用case的情况下,否则不会调用该方法。 但这会调用我的,并在内抛出空指针。因为我的行为不会调用,所以我如何在不调用的情况下测试它。

  • 实际上,它的测试如果eat方法对宠物有效,但我也需要检查feedPet方法对玩家也有效。 任何想法或建议都非常感谢。

  • 问题内容: 基于此答案,我想在一个将从另一个文件导入的类中构建一个异步websoket客户端: 然后将其导入中,其中包含以下内容: 但是它检索到以下错误: 这是怎么回事?如果mtest.get_ticks开头是单词,为什么我不能访问它? 问题答案: 最后,我可以找到正确的方法(特别感谢 @dirn ) 这在main.py中: 这是输出: 任何改进的技巧都值得欢迎!;)

  • 问题内容: 我有一个旧类,其中包含用于实例化LoginContext()的new()调用: 我想使用Mockito测试类来模拟LoginContext,因为它要求在实例化之前设置JAAS安全性,但是我不确定如何在不更改login()方法以外部化LoginContext的情况下进行此操作。是否可以使用Mockito模拟LoginContext类? 问题答案: 对于将来,我会推荐伊兰·哈雷尔(Eran

  • 我有一个helper类,它包含一个公共静态方法: 一个定制服务类使用上面的ProductHandlerManager: 我想在自定义服务类中使用单元测试方法。我尝试使用mockito模拟测试中的部分,但是mockito不支持静态方法模拟。那么我如何使用mockito来单元测试函数呢? 请不要建议我使用Powermock,因为我读过一些文章,说如果我需要模拟静态方法,这表明设计不好。但是我可以接受关

  • 我有一个jsf spring应用程序,并使用mockito进行单元测试。在模拟中运行测试时,我一直得到。对于不存在。 要嘲弄的方法 我的JUnit测试是用注释的

  • 我正在用Mockito为一个项目设置jUnit测试。在被测系统(DrawingService)中调用方法时遇到问题。模拟包括图形和IDrawingRepository。 我不熟悉TDD、单元测试和一般的模拟,所以我可能犯了一些noob错误?任何帮助都将不胜感激。 以下是测试课程: 以下是正在测试的系统: