【问题标题】:How to inject mocked object into another already mocked object如何将模拟对象注入另一个已经模拟的对象
【发布时间】:2016-01-06 14:35:56
【问题描述】:

我有一个这样嘲笑的课程:

@Mock
private MyClass1 mockMyClass1;

假设这个类看起来像这样:

public class MyClass1 {
  @Autowired
  private MyInnerClass myInnerClass;
}

当我模拟MyClass1 时,MyInnerClass 将被初始化为null。是否可以用另一个反对的模拟来初始化该私有字段?我希望myInnerClass 成为这样的模拟:

@Mock
private MyInnerClass myInnerClass;

如果我使用以下代码:

@InjectMocks
private MyClass1 mockMyClass1;
@Mock
private MyInnerClass myInnerClass

这会将MyClass1 中的私有MyInnerClass 初始化为模拟对象,但是这样mockMyClass1 本身就不再是模拟对象了,不是吗(我只是在真正的类,就像@Autowired 会在它里面注入一个真实的对象)?如果我对@InjectMock@Mock 的理解有误,您能否纠正我的逻辑?另外,我如何在另一个模拟对象中注入一个模拟对象(不使用设置器/构造函数)?

【问题讨论】:

  • 你应该对行为而不是实现进行存根。

标签: java spring testing mockito


【解决方案1】:

您误解了mock 是什么。

当您模拟MyClass1 时,被模拟对象的MyInnerClass 类型的内部字段不再存在。因此,尝试将某些东西注入到模拟中是没有意义的。

模拟是通过说当你与它交互时它应该做什么来控制的。你存根它的公共方法来做你想让他们做的事情。你给予行为。如果您没有配置模拟,唯一的默认行为(可能特定于 Mockito)是返回 null(但请注意,它不会返回 null,因为某些内部变量是 null,它返回是因为Mockito 决定这就是它应该返回的内容;也许另一个模拟框架决定它应该抛出异常,谁知道呢?)。

例如,假设您的真实班级是:

class MyClass1 {
    private MyInnerClass myInnerClass;
    public MyInnerClass getMyInnerClass() {
        return myInnerClass;
    }
}

现在考虑 mock 该类的模拟。如果您调用mock.getMyInnerClass(),它不是将被调用的真正方法。它将返回不是myInnerClass 的值。它将返回null,或者如果您已使用

存根该方法
when(mock.getMyInnerClass()).thenReturn(something);

然后它将返回something

所以回答你的问题:你不能这样做,因为模拟不是这样工作的。

【讨论】:

  • 有时将模拟对象放入另一个模拟对象可能是有意义的。例如,如果某个类同时使用 MyClass1 和 MyInnerClass 实例,并且您不希望两次实现模拟逻辑。还是我错了?
  • @MateuszDryzek 模拟类没有变量的概念。它消失了。噗。您只需为模拟定义行为。当你调用它的方法时它应该做什么。真实类的真实代码已不复存在。
  • @Tunaki 我遇到了这个问题,因为 MyClass1 是一个服务层类,它调用存储库(数据库)层方法(MyInnerClass 是一个存储库层类)。我想测试 MyClass1 逻辑,而不与数据库层进行实际交互(这就是我希望 MyInnerClass 成为模拟的原因)。你让我意识到我的逻辑中的一个流动。目前我模拟 MyClass1 ,然后对我有兴趣测试的所有方法执行 .thenCallRealMethod() 。我可能应该做的是模拟 MyInnerClass 并在 MyClass1 中使用 InjectMock 注入它。
  • @AntonBelev 是的,这正是你应该做的以及应该如何使用模拟 :)!
  • @AntonBelev 这让我很高兴:D
【解决方案2】:

您根本不应该真正使用 InjectMocks 注释(要了解原因,您可以阅读此article)。

您可以只为 MyClass1 实现 Autowired 构造函数,而不是 Autowired 字段。然后您可以简单地将您的 MyInnerClass 模拟引用作为构造函数参数传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    相关资源
    最近更新 更多