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

用Mockito嘲弄间谍方法

奚光霁
2023-03-14

我正在为FizzConfigurator类编写一个单元测试,该类如下所示:

public class FizzConfigurator {
    public void doFoo(String msg) {
        doWidget(msg, Config.ALWAYS);
    }

    public void doBar(String msg) {
        doWidget(msg, Config.NEVER);
    }

    public void doBuzz(String msg) {
        doWidget(msg, Config.SOMETIMES);
    }

    public void doWidget(String msg, Config cfg) {
        // Does a bunch of stuff and hits a database.
    }
}

我想编写一个简单的单元测试,它将dowidget(String,Config)方法存根(这样它就不会实际触发并命中数据库),但它允许我验证调用doBuzz(String)是否最终执行dowidget。Mockito似乎是这份工作的合适工具。

public class FizzConfiguratorTest {
    @Test
    public void callingDoBuzzAlsoCallsDoWidget() {
        FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
        Mockito.when(fixture.doWidget(Mockito.anyString(), Config.ALWAYS)).
            thenThrow(new RuntimeException());

        try {
            fixture.doBuzz("This should throw.");

            // We should never get here. Calling doBuzz should invoke our
            // stubbed doWidget, which throws an exception.
            Assert.fail();
        } catch(RuntimeException rte) {
            return; // Test passed.
        }
    }
}

这似乎是一个很好的游戏计划(至少对我来说)。但当我实际编写代码时,在测试方法的第2行(mockito.when(...)行)出现以下编译器错误:

类型Mockito中的(T)不适用于参数(void)时的方法

我看到Mockito无法模拟返回void的方法。所以我问:

  1. 我是否正确地接近此测试设置?或者有没有更好的mockito推荐的测试方法,让dobuzz在引擎盖下调用dowidget?和
  2. 对于嘲弄/截短dowidget我可以做什么,因为它是整个fizzconfigurator类中最关键的方法?

共有3个答案

茹展鹏
2023-03-14

在我的例子中,对于我试图存根的方法,我传入了不正确的匹配器。

我的方法签名(对于我试图存根的超类方法):String,Object。

我路过:

MyMethod(“String”,mockito.nullable(ClasStype.Class))并获取:

提示:1。缺少thenReturn()%2。您正在尝试截尾一个不受支持的final方法3:在“then return”指令完成之前,您正在截尾内部另一个模拟的行为

在另一个参数中使用匹配器时,我们也需要为字符串使用匹配器:

MyMethod(eq(“String”),mockito.nullable(ClasStype.Class))

希望这有帮助!

章昊
2023-03-14

这清楚地表明DowIdGet方法应该属于FizzConfigurator所依赖的另一个类。

在您的测试中,这个新的依赖项将是一个模拟,您可以很容易地验证它的方法是否是用verify调用的。

孙岳
2023-03-14

我不会使用异常来测试,而是使用验证。另一个问题是不能使用when()返回void的方法。

我会这样做:

FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
doNothing().when(fixture).doWidget(Mockito.anyString(), Mockito.<Config>any()));
fixture.doBuzz("some string");
Mockito.verify(fixture).doWidget("some string", Config.SOMETIMES);
 类似资料:
  • 问题内容: 使用Mockito间谍的用例是什么? 在我看来,每个间谍用例都可以使用callRealMethod进行模拟处理。 我可以看到的一个区别是,如果您希望大多数方法调用都是真实的,则可以节省一些代码行以使用模拟与间谍。是这样还是我错过了更大的前景? 问题答案: 答案在文档中: 真正的部分模拟(自1.8.0开始) 最后,在邮件列表上进行了许多内部辩论和讨论之后,Mockito添加了部分模拟支持

  • 我需要测试一些遗留代码,这些代码在a方法调用中使用了单例。测试的目的是确保类sunder测试对singletons方法进行调用。我在SO上看到过类似的问题,但所有的答案都需要其他依赖项(不同的测试框架)--不幸的是,我仅限于使用Mockito和JUnit,但对于这样流行的框架,这应该是完全可能的。 单身人士: 正在测试的类: 单元测试: 这个想法是配置可怕的单例的预期行为,因为被测试的类将调用它的

  • 在helper类的静态方法中调用时,它会抛出一个NPE。我所做的是嘲笑MarkupMaker和它的返回值(一个Markup实例)。最后,我希望调用标记实例的。无论我做什么-的调用都是抛出一个NPE。我找不到任何文档告诉我如何在spock中详细模拟方法调用值。 编辑:我添加了示例。的调用返回null,即使我在spock测试中对其进行了嘲弄。 test.groovy java(执行模拟对象的方法) j

  • 问题内容: 我有内部类的课程,如下所示: 模仿测试如下所示:build.gradle: 测试: 第一次测试正在按预期方式工作。第二个永远不会被检测为“已调用”,尽管在日志中我看到的是。有什么问题吗?:) 谢谢! 问题答案: 怎么了? 好吧,这里的问题非常微妙,当您调用时,会在实例背后创建某种装饰器,以允许监视实例上的所有方法调用。因此,您可以检查给定方法被调用了多少次, 但是在装饰器 上 却 没有

  • 正在测试的类: 下面是测试代码。我模拟了测试中的类class,并覆盖了方法getFruits的返回值。但是当我运行mock时,我没有得到预期的mock返回值。Easymock可以将返回值替换为被测试类的方法,如果这些方法是显式模拟的。当我模拟真实的对象方法时,如何获得模拟的返回值。

  • 引用同一类中的模拟方法 测试类 当调用真正的类temp到methodA时,应该返回模拟的方法B的值。从而返回true。为什么这不正确。我遇到了同样的问题。我想在真实的类上运行测试,而不是像答案中建议的那样在模拟对象上运行测试。我想运行类methodA,并在调用它时期待模拟对象spyTemp methodB的值