简体   繁体   English

模拟接口/抽象类时Mockito InvalidUseOfMatchersException

[英]Mockito InvalidUseOfMatchersException while mocking an Interface/Abstract class

I recently upgrade Maven Surefire plugin to version v2.14.1 (from v2.6) in my project. 我最近在我的项目中将Maven Surefire插件升级到版本v2.14.1(从v2.6开始)。 After this upgrade Mockito started throwing InvalidUseOfMatchersException in all JUnit tests where a Mockito.mock() method is invoked on an 'interface' or 'abstract class'. 在此次升级之后,Mockito开始在所有JUnit测试中抛出InvalidUseOfMatchersException,其中在“接口”或“抽象类”上调用Mockito.mock()方法。 Same Unit Test works fine when executed through Eclipse, but always fails while building with Maven. 通过Eclipse执行相同的单元测试工作正常,但在使用Maven构建时总是失败。

 Here are few examples of calls that are failing:

 i) DataSource dataSource = Mockito.mock(DataSource.class);

ii) DatabaseMetaData metaData = mock(DatabaseMetaData.class);

iii) ResultSet rs = mock(ResultSet.class);

InvalidUseOfMatchersException is almost never caused by a call to Mockito.mock() ; InvalidUseOfMatchersException几乎从不是由对Mockito.mock()的调用引起的; rather, the call to Mockito.mock() tells Mockito to validate that it's not in the middle of something , which is when it determines that it should throw a InvalidUseOfMatchersException . 相反,对Mockito.mock()的调用告诉Mockito 验证它不在某事物的中间 ,这是因为它确定它应该抛出InvalidUseOfMatchersException Your error is probably related to Maven/Surefire because it's executing your test methods in a different order than Eclipse does, or because Maven is reusing a JVM where Eclipse isn't. 您的错误可能与Maven / Surefire有关,因为它以与Eclipse不同的顺序执行您的测试方法,或者因为Maven正在重用Eclipse不在的JVM。

Mockito matchers are static functions that return dummy values (but that secretly log their calls with Mockito). Mockito匹配器是静态函数,它返回虚拟值(但是用Mockito秘密记录它们的调用)。 Internally, Mockito keeps a stack of previously-called matchers , one per thread, so if you call a Matcher at the end of a test method it will linger around to pollute the next test method in the same thread. 在内部,Mockito保留了一堆先前称为匹配器的堆栈 ,每个线程一个,因此如果在测试方法结束时调用Matcher,它将会在同一个线程中徘徊以污染下一个测试方法。

The easiest way to pin this down is to put a call to Mockito.validateMockitoUsage() in your tearDown method (JUnit3) or an @After method (JUnit4). 解决此问题的最简单方法是在tearDown方法(JUnit3)或@After方法(JUnit4)中调用Mockito.validateMockitoUsage() )。 That will cause the test method that misuses Mockito to fail there, rather than in whatever next method that runs. 这将导致误用Mockito的测试方法在那里失败,而不是在下一个运行的方法中。

As for the actual Matcher misuse? 至于实际的Matcher滥用? Double-check that every time you use a Matcher from org.mockito.Mockito or org.mockito.Matchers , you're actually matching every single argument in the function; 仔细检查每次使用org.mockito.Mockitoorg.mockito.Matchers的Matcher时,您实际上是在匹配函数中的每个参数; I went over the reasons in a separate SO answer . 我在一个单独的答案中回答了原因。 Be particularly wary of calling other mocks from within your calls to when or verify (which interferes with Mockito's static magic) or when trying to stub or verify any method marked final (which will fail silently because the VM calls the actual implementation instead). 特别警惕从你的调用中调用其他模拟whenverify (这会干扰Mockito的静态魔法)或者尝试存根或验证任何标记为final方法(由于VM调用实际的实现而无声地失败)。

Hope that helps! 希望有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM