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

Mockito如何监视模拟内部方法调用?

阎弘雅
2023-03-14

我一直认为Mockito工作某种代理之类的东西。但现在我发现,Mockito允许我做一些像

class A {
  public String m1() {
    return m2();
  }

  public String m2() {
    return "Hello";
  }
}

class TestA {
  public testM1() {
    A a = Mockito.spy(A.class);
    when(a.m2()).thenReturn("Bye");
    Assert.assertEquals(a.m1(), "Bye");
  }
}

这不适用于代理。它是如何做到这一点的?这种技术可以用来调用内部AOP方法吗?(请参见Spring AOP不适用于另一个方法中的方法调用)

共有1个答案

顾池暝
2023-03-14

Mockito确实与代理合作,并支持间谍。不过,您的语法有点不对劲:

/* BAD */  A a = Mockito.spy(A.class);
/* GOOD */ A a = Mockito.spy(new A());

不同行为的原因是a没有将参数委托给spy(),而是将字段值复制到一个全新生成的子类中,并重写了它的所有方法。因此,在Spring中,对this的引用是指未包装的实例,而在Mockito中,对this的引用是指包装的对象-包括在M1中的m2()调用中对this的隐式引用。

尽管这听起来似乎允许使用AOP,但我无法测试它是否有效,我认为这将取决于Mockito和Spring AOP的实现细节(以及包装发生的顺序)。

 类似资料:
  • 我是莫基托的新手。我试图通过模拟数据库交互为服务编写jnuit: 我有下面的类(只是实际类的代表) 我的测试课就像是 但是当我运行这个测试时,它仍然调用实际的db调用并从DB中检索值,而不是模拟值,我应该模拟sql连接和非默认构造函数吗?我一无所知。 -- 更新 正如人们所建议的那样,我将DAO实例化移动到我的服务构造函数中,并且还使用了Spy,但是我仍然调用了实际的DB调用而不是模拟调用。

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

  • 问题内容: 我在某些测试中使用Mockito。 我有以下课程: 我只想模拟的第二个调用。第一次调用必须调用real方法。有没有办法做到这一点? 问题答案: Mockito不支持此功能。 这可能不是你要寻找的答案,但是你看到的是不采用设计原则的症状: 偏重于继承而不是继承 如果你提取策略而不是扩展超类,那么问题就不存在了。 但是,如果不允许你更改代码,但无论如何都必须对其进行测试,并且以这种尴尬的方

  • 问题内容: 如何用void返回类型模拟方法? 我实现了一个观察者模式,但是我无法用Mockito对其进行模拟,因为我不知道如何做。 我试图在互联网上找到一个例子,但没有成功。 我的课看起来像这样: 系统不会通过模拟触发。 我想显示上述系统状态。并根据他们做出断言。 问题答案: 看看Mockito API文档。由于链接的文档提到(点#12),你可以使用任何的家人从框架的的方法来嘲笑无效的方法。 例如

  • 我有一个调用Repository方法并返回列表的服务类。现在我想嘲笑它。我的单元测试场景如下: 向模拟存储库添加一些模拟对象 返回模拟对象列表的查询服务类 断言列表大小 我的存储库类: 我的服务等级: 我的对象类: 和我的测试课程: 但是由于我是Mockito的新手,这对我来说有点困难。我想知道如何从FoodService类中获取列表,并且它应该返回在测试类中制作的假对象。