【问题标题】:JUnit/Mockito: ArgumentCaptor running before the JUnit test executes?JUnit/Mockito:ArgumentCaptor 在 JUnit 测试执行之前运行?
【发布时间】:2020-02-26 03:47:43
【问题描述】:

我有如下 JUnit 测试:

@Autowired
MyService myservice;

@Before
public void init() {
   myservice.doStuff(new MyObj());
}

@Test
public void test() {
   ArgumentCaptor<MyObj> captor = ArgumentCaptor.forClass(MyObj.class);
   myservice.doStuff(new MyObj());
   verify(myservice, atLeastOnce()).doStuff(captor.capture());
   captor.getAllValues(); //this returns 2 - one for the @Before and one for right above
}

正如注释代码中所提到的,即使捕获器是在 @Before 之后创建的,捕获器也会捕获这两个调用。为什么会这样?如何仅捕获测试中的调用?

【问题讨论】:

    标签: spring junit mocking mockito


    【解决方案1】:

    此流程中似乎有问题,我会解释并希望这会引导您找到解决方案:

    首先,ArgumentCaptor 仅用于模拟。所以myservice 必须是一个模拟, 我期待看到类似@MockBean 或@Mock 之类的东西,如果你正在运行一个没有弹簧的普通模拟测试。

    现在假设它是一个模拟,你为什么要在@Before 阶段的模拟上调用一个方法doStuff。如果你有很多测试,如果你想设置一些适用于课堂上所有测试的全局期望,我可以理解,但这对我来说似乎很可疑。

    现在,当您使用 verify 时,您实际上所说的是:

    Mockito,确保我的模拟 myservice 调用了方法 doStuff(至少一次),为了进一步验证,我想“捕获”在方法调用时传递给模拟的参数。

    使用这种方法可以理解,参数捕获获取有关所有调用的所有信息,我相信这是设计使然。

    明确一点,@Before 方法与 mockito 无关,它是一个纯粹的 JUnit 钩子,所以当它被 JUnit 框架调用时,所有的 mock 都已经初始化并准备“记录”所有有关代码将对它们执行的所有操作(我的意思是方法调用)的相关信息。

    【讨论】:

    • 所以这只是一个说明问题的例子......在实际代码中,@Before 中的测试设置代码在内部最终会调用服务(实际上是@SpyBean in真实代码)...所以我们总是会从设置代码中获得一两个额外的调用...我想知道是否有办法排除这些(除了在验证之前手动过滤)
    猜你喜欢
    • 2010-11-14
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    相关资源
    最近更新 更多