使用 Mockito 存根并执行测试方法

2022-08-31 17:14:23

我最近问了几个面向jUnit和Mockito的问题,我仍然在努力掌握它。这些教程都是针对非常简单的示例,因此我正在努力扩展我的测试用例以适用于我的类。

我目前正在尝试为 Web 应用中的某个代理中的方法编写一些测试用例。该方法与代理中的其他几个方法交互,以验证某些对象。我现在只想测试这一种方法。

以下是我试图做的事情:

  1. 创建我的代理的Mockito对象,如下所示:

    MyProcessingAgent mockMyAgent = Mockito.mock(MyProcessingAgent.class);

  2. 使用 Mockito 设置存根(希望是正确的术语),如下所示:

    Mockito.when(mockMyAgent.otherMethod(Mockito.any(arg1)).thenReturn(requiredReturnArg);

  3. 尝试像这样执行我的方法:

    List myReturnValue = mockMyAgent.methodThatNeedsTestCase();

我本来以为在 中出现,但收到 0,所以我尝试调试。当我调用该方法时,它永远不会执行。我在方法的第一行有一个调试点,永远不会被触及。myReturnValue

如果我想在类的一个方法中执行代码,但强制类中的其他方法(尝试与外部世界的数据库交互的方法)返回伪造的值。这在Mockito上可能吗?

看来我目前的方法不是一种正确的测试风格,但我不知道如何前进。我是否可以模拟我的类并像往常一样执行一个方法,而其他方法则被存根以返回我的给定值,以便我在测试此方法期间不必处理数据访问?


答案 1

您将 a 与 . 混淆。MockSpy

在 mock 中,所有方法都存根并返回“智能返回类型”。这意味着在模拟类上调用任何方法都不会执行任何操作,除非您指定行为。

在间谍中,类的原始功能仍然存在,但您可以在间谍中验证方法调用,也可以重写方法行为。

你想要的是

MyProcessingAgent mockMyAgent = Mockito.spy(MyProcessingAgent.class);

一个简单的例子:

static class TestClass {

    public String getThing() {
        return "Thing";
    }

    public String getOtherThing() {
        return getThing();
    }
}

public static void main(String[] args) {
    final TestClass testClass = Mockito.spy(new TestClass());
    Mockito.when(testClass.getThing()).thenReturn("Some Other thing");
    System.out.println(testClass.getOtherThing());
}

输出为:

Some Other thing

注意:你真的应该尝试模拟被测试类的依赖关系,而不是类本身。


答案 2

因此,嘲笑被测类的想法是对测试实践的诅咒。你不应该这样做。因为您已经这样做了,所以您的测试正在进入 Mockito 的模拟类,而不是您正在测试的类。

间谍活动也不起作用,因为这只会在spied类周围提供包装器/代理。一旦执行在类内部,它就不会通过代理,因此不会击中间谍。更新:虽然我相信Spring代理也是如此,但对于Mockito间谍来说似乎并非如此。我设置了一个方案,其中方法调用 .我监视对象和存根到.当我在测试中调用时,未达到类。Mockito 调用存根。因此,使用间谍来完成所要求的事情是可能的。但是,我要重申,我认为这是不好的做法(恕我直言)。m1()m2()m2()doNothingm1()m2()

您应该模拟所测试的类所依赖的所有类。这将允许您控制被测方法所调用的方法的行为,因为您可以控制这些方法调用的类。

如果您的类创建其他类的实例,请考虑使用工厂。


推荐