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

为什么Mockito@InjectMocks可能是要避免的事情?

孙绍辉
2023-03-14

为什么@InjectMocks可能是这种测试要避免的事情。

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

    @Mock
    private Bar bar;

    @InjectMocks
    private Foo foo; // created by Mockito

    @Test
    public void shouldCallMethod() {

        // when
        foo.myMethod();

        // then
        ...
    }
}
public class Foo {

    private final Bar bar;

    public Foo(Bar bar) {
        this.bar = bar;
    }
...

我在对这个答案的评论中读到了这一点:https://stackoverflow.com/a/21172873/516167

标记应在其上进行注射的字段。

  • 允许速记模拟和间谍注入
  • 最小化重复模拟和间谍注入

参考:@InjectMocks JavaDoc。

共有2个答案

娄阳舒
2023-03-14

此外,有些人建议依赖项应该由构造函数添加,而不是由setter添加,这样在编译时就可以保证正确的依赖项。看这个。

通过使用构造函数,您被迫限制要用作依赖项的组件的数量,以降低复杂性。(这可能不容易,而且在Spring会改变很多事情的方式)。

更新:在构造函数中使用自动连接的依赖项一段时间后,我清楚地注意到测试不那么脆弱。当依赖关系更改时,我仍然需要更改测试,但编译器告诉我应该在哪里更改它以及更改的大小。更好的是,现在我可以区分在编译时对测试进行更改以适应新代码,以及此代码在运行时添加的故障。

谭锐藻
2023-03-14

我看到的唯一缺点是您必须遵守它的规则。如果您不使用@InjectMocks,您可能会有更多的控制权

从他们的文档中,我以粗体添加了一些:

Mockito将尝试仅通过构造函数注入、setter注入或属性注入按顺序注入模拟,如下所述。如果以下任何策略失败,则Mockito不会报告失败;即您必须自己提供依赖项。

构造函数注入;选择最大的构造函数,然后使用仅在测试中声明的模拟解析参数。注意:如果找不到参数,则传递null。如果需要不可模拟的类型,则不会发生构造函数注入。在这些情况下,您必须自己满足依赖关系。

属性设置器注入;模拟将首先按类型进行解析,然后,如果存在多个相同类型的属性,则通过属性名称和模拟名称的匹配进行解析。注1:如果您有相同类型(或相同擦除)的属性,最好用匹配的属性命名所有@Mock注释字段,否则Mockito可能会混淆,不会发生注入。

注意 2:如果@InjectMocks实例之前未初始化并且具有 no-arg 构造函数,则将使用此构造函数对其进行初始化。

字段注入;模拟将首先按类型解析,然后,如果有几个相同类型的属性,则通过字段名称和模拟名称的匹配来解析。注意1:如果您有具有相同类型(或相同擦除)的字段,最好将所有@Mock注释字段命名为匹配字段,否则Mockito可能会混淆并且不会发生注入。

注意 2:如果@InjectMocks实例之前未初始化并且具有 no-arg 构造函数,则将使用此构造函数对其进行初始化。

 类似资料:
  • 问题内容: 通常我会尽可能避免转换类型,因为我认为这是不良的编码实践,并且可能会导致性能下降。 但是,如果有人要我解释为什么会这样,我可能会像前灯中的鹿一样看它们。 那么,为什么/何时铸造不好? 它对于Java,C#,C ++是通用的,还是每个不同的运行时环境都按照自己的方式处理? 欢迎使用任何语言的细节,例如为什么在c ++中不好? 问题答案: 您已经用三种语言标记了这三种语言,答案在三种语言之

  • 在React中,我尝试了两种方法: 然后更改状态this.setState(this.state) 克隆状态,更改状态克隆,然后更改此.setState(stateClone) 它们都起作用,产生相同的结果。为什么建议(在文档中)设置为状态克隆(使用Object.assign),而不是设置为状态本身?状态的对象标识在React中重要吗(没有Redux)?似乎只要调用setState,不管状态对象标

  • 问题内容: 我已经在多个地方多次看到过这种情况,但是从未找到令人满意的解释来说明为什么会这样。 因此,希望这里会介绍一个。为什么我们(至少通常)不使用和? 编辑:我看到人们以为这个问题与Web服务器有关,但事实并非如此。我可以理解为什么传递给未经处理的字符串可能很糟糕。在非Web应用程序中不好吗? 问题答案: 通常有更清晰,更直接的方法来获得相同的效果。如果构建复杂的字符串并将其传递给,则代码将难

  • 问题内容: Process p = Runtime.getRuntime().exec(command); is = p.getInputStream(); byte[] userbytes = new byte[1024]; is.read(userbytes); 我想从java在linux os中执行shell命令。但是Pmd报告说不要使用Java Runtime.exec()。为什么?是什么

  • 问题内容: 假设我们在页面上有一个DIV ,并且想要将该DIV的内容复制(“复制粘贴”)到另一个DIV中。我们可以这样做: 或使用jQuery: 但是,看来此方法不是一个好主意,应避免使用。 (1)为什么要避免这种方法? (2)应该怎么做呢? 更新: 为了解决这个问题,我们假设DIV中没有ID为ID的元素。 (对不起,我忘了在原始问题中介绍此案。) 结论: 我已经在下面发布了我对这个问题的答案(如

  • 我的公司不允许使用Mockito。在单元测试中验证。甚至有一个定制的声纳规则 规则如下 应该通过断言来验证结果,而不是使用“验证到执行”过程验证。因为如果我们验证流程,在流程更改后需要更多的努力来维护测试,但输入和输出保持不变。确保每一行代码都对结果有影响,并断言结果以证明逻辑正确 不合规代码示例 合规解决方案 对于数据库或中间件操作,断言使用嵌入式数据库或中间件成功写入数据。 对于restful