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

使用Mockito模拟方法

皇甫心思
2023-03-14

使用mockito模拟一个方法会确保永远不会调用被模拟的方法吗?我有一个主类,它包含一些我想为其编写单元测试的代码,还有一个单元测试类MainTest,它包含主类的单元测试。

eg:

源类:

package abc;

public class Main {

    public int check1() {
        int num = 10;
        num = modify(num);
        return num;
    }

    public int modify(int num) {
        if (num % 10 == 0) return num / 10;
        return -1;
    }
}

JUnit测试(使用mockito)

package abc;

import junit.framework.Assert;

import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;

public class MainTest {

    private static Main main;

    @BeforeClass
    public static void setUp() {
        main = Mockito.mock(Main.class);
        Mockito.when(main.modify(10)).thenReturn(5);
    }

    @Test
    public void testCheck1() {
        Test1 main1 = new Main();
        int num = main.check1();
        Assert.assertEquals(5, num);
    }
}

这项测试失败了。为什么?

共有3个答案

姚臻
2023-03-14

虽然我迟到了,但它可能对某些人有用。只是添加到@ ViVaveVo的答案:当使用间谍时,请考虑DeleTurn回答“Sun”()一系列的破解方法。有时,用when(Object)来对付间谍是不可能或不切实际的。更多信息请点击这里

阎佑运
2023-03-14

测试的问题是,您没有使用新创建的main 1对象。

如果你想改变被测系统(SUT)的行为,你通常会这样做:

@Test
public void testCheck1() {
    Test1 main1 = new Main(){
        public int modify(int num) {
            return 5; // hard coded return value
        }
    };
    int num = main1.check1();
    Assert.assertEquals(5, num);
}

这将创建一个Main的子类,其中包含一个修改方法的新实现。这是替换SUT中难以测试的方法的重要技术。您通常会使用它来避免昂贵的远程呼叫或类似情况。

当然可以使用这样的Mockito间谍:

@Test
public void testCheck1() {
    Test1 main1 = spy(new Main());
    stub(main1.modify(10)).toReturn(5);

    int num = main1.check1();
    Assert.assertEquals(5, num);
}
艾俊悟
2023-03-14

编辑因为您没有为check 1()提供行为。所有方法都会被嘲笑,所以如果您不提供行为,check 1()返回int返回类型的默认值,即0。此外,check 1(),因为它是mocked,甚至不能调用修改()

如果你试图测试一个类,你永远不要嘲笑测试下的类。在极少数情况下,您可能不得不窥探正在测试的类。相反,你只嘲笑合作者。

我猜你的例子是人为的(我希望如此)。但是,如果你正在编写和测试一个类,你认为你想修改一些内部方法的行为,我看到两种可能性:

  1. 您可能需要将您想要模拟的方法的功能重构为合作者类。那么作为合作者继续嘲笑这种行为是有意义的。
  2. 您可能还需要修改API,以便传入将要更改的内容。在你的例子中,check 1()硬编码它传递给修改()的值,这就是为什么你试图模拟修改()。相反,如果该值是check 1()的参数或类Main中的可设置字段,那么甚至不需要使用mock。
 类似资料:
  • 我是莫基托的新手。我试图通过模拟数据库交互为服务编写jnuit: 我有下面的类(只是实际类的代表) 我的测试课就像是 但是当我运行这个测试时,它仍然调用实际的db调用并从DB中检索值,而不是模拟值,我应该模拟sql连接和非默认构造函数吗?我一无所知。 -- 更新 正如人们所建议的那样,我将DAO实例化移动到我的服务构造函数中,并且还使用了Spy,但是我仍然调用了实际的DB调用而不是模拟调用。

  • 我的测试存根是 我在这里做错了什么?

  • 问题内容: 我有四个让我们说A,B,C,D的类,每个类都从另一个调用方法。 现在我已经模拟了类A,并且想模拟使用嘲笑的方法 并希望在递归方法调用上获取“ foo” 应该回来 我试过了 when(a.getB()。getC()。getD())。thenReturn(“ foo”); 但是得到了nullPointerException 然后我尝试 doReturn(“ foo”)。when(a.get

  • 我有4个类让说A,B,C,D,每一个调用的方法从另一个。 现在我已经模拟了类A,并想使用mockito模拟一个方法 但得到nullPointerException 然后我试着 doReturn(“foo”).When(A.getb().getc().getd()); 但我不能一次就做到吗?如有任何帮助,我们将不胜感激。