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

Kyl*_*yle 47 java junit mocking mockito

我最近问了几个关于jUnit和Mockito的问题,我仍然在努力解决这个问题.这些教程都是非常简单的示例,所以我很难扩展我的测试用例以适应我的课程.

我正在尝试为我在webapp中的一个代理中的方法编写一些测试用例.该方法与代理内部的其他几种方法交互以验证某些对象.我现在只想测试这一种方法.

这是我试图做的事情:

  1. 像这样创建我的代理的Mockito对象:

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

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

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

  3. 尝试执行我的方法,如下所示:

    List myReturnValue = mockMyAgent.methodThatNeedsTestCase();

我期待的东西myReturnValue,但收到0反而所以我试图调试.当我调用该方法时,它永远不会执行.我在方法的第一行有一个调试点,永远不会被触及.

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

看来我目前的方法不是一种正确的测试方式,但我不确定如何向前推进.我可以模拟我的类并让一个方法像正常一样执行,而其他方法被存根以返回我给定的值,这样我在测试这个方法时就不必处理数据访问了吗?

Bor*_*der 72

你混淆了Mock一个Spy.

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

在间谍中,类的原始功能仍然存在,但您可以在间谍中验证方法调用并覆盖方法行为.

你想要的是什么

MyProcessingAgent mockMyAgent = Mockito.spy(MyProcessingAgent.class);
Run Code Online (Sandbox Code Playgroud)

一个简单的例子:

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());
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Some Other thing
Run Code Online (Sandbox Code Playgroud)

注意:您应该尝试模拟正在测试的类的依赖关系,而不是类本身.


Joh*_*n B 6

因此,模拟测试类的想法是对测试实践的厌恶.你不应该这样做.因为你已经这样做了,你的测试是进入Mockito的模拟课程,而不是你正在测试的课程.

间谍也不会起作用,因为这只提供了一个围绕间谍类的包装器/代理.一旦执行在类中,它将不会通过代理,因此不会打到间谍.更新:虽然我相信这对于Spring代理来说是真实的,但对于Mockito间谍来说似乎并非如此.我设置了一个方法m1()调用的场景m2().我是间谍的对象和存根m2()doNothing.当我m1()在我的测试中调用时,m2()没有到达类.Mockito调用存根.因此,使用间谍来完成所要求的事情是可能的.但是,我要重申,我认为这是不好的做法(恕我直言).

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

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