我最近将一个单元测试套件迁移到了Junit 5.8.2和Mockito 4.5.1 + Mockito Inline,以允许静态模拟。Powermock已删除。
迁移了2000多个测试,当在IDE(IntelliJ)中运行时,它们都成功运行。这两个都是IDEA和Gradle Runner。
然而,当Jenkins尝试运行它们时,有超过900个失败的测试。抛出的一些异常。
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Boolean cannot be returned by someMethod()
someMethod() should return Date`
我理解是什么导致了这些错误,因为我在迁移过程中多次看到它们,所以这不是重复的解决方案。(除非Jenkins环境有什么不同)抛出此类异常的代码不应该抛出它们。在IDE中没有。这是专门扔在Jenkins。
一个我以前从未见过的异常也被抛出。
org.mockito.exceptions.misusing.UnfinishedMockingSessionException:
Unfinished mocking session detected.
Previous MockitoSession was not concluded with 'finishMocking()'.
For examples of correct usage see javadoc for MockitoSession class.
大多数例外都属于这种类型。然而,MockitoSession接口并没有在测试套件的任何地方使用。所有模拟都使用@ExtendWith(MockitoExtension.class)
初始化
我不知道是什么引起的。
Jenkins运行的Java/Junit/Mockito/Spring版本与IDE中的代码相同。在我看来很明显,不同的环境导致了这个问题。然而,有什么区别,我该如何找到它?
我试图在本地重现结果,但无法做到。对此,任何想法也是受欢迎的。
1条答案
按热度按时间ztigrdn81#
弄清楚发生了什么。
我们尝试了几种方法。
然而,这些方法会调用一些包含静态字段/方法的类,这些静态字段/方法没有被静态地模仿,因为它们在意大利面条中太深了,我们甚至没有意识到代码流已经到了那里。
其中一些静态方法将联系DB并从那里提取信息,然后在单元测试中使用。
当在本地运行时,这不会出现任何问题,因为每个开发人员都有一个本地数据库,并且连接成功。
然而,Jenkins环境没有DB,因此当静态方法初始化并尝试连接时,会抛出DB连接异常。
但是,如上所述,该异常是在
try-with-resources
mockStatic()
块中抛出的,并且由于静态模拟没有完成,因此任何后续对mockStatic()
类的尝试都将导致前面提到的UnfinishedMockingSessionException
。解决方案是找到静态模拟任何试图与数据库通信的方法。
我仍然不明白的是,为什么在
try-with-resources
mockStatic()
块中抛出的异常会阻止任何后续的尝试。在我看来,它应该是本地化的。抛出的异常掩盖了真实的的问题。不管怎样,我不在那里工作了,也不在乎了。