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

Mockito——在使用maven运行时,InvalidUseOfMatchersException,但直接从eclipse工作

漆雕修能
2023-03-14

我有一个rest调用的mock方法。

public void createRestClientMock() {
        org.mockito.Mockito.when(
                restClient.sendResponse(org.mockito.Matchers.anyString(),
                        org.mockito.Matchers.anyString())).thenAnswer(
                new Answer<Object>() {
                    public Object answer(InvocationOnMock invocation) {
                        Object[] args = invocation.getArguments();
                        actualResponse = args[1].toString();
                        LOG.debug(actualResponse);
                        return null;
                    }
                });
    }

当我从eclipse运行junit时,真正的方法就像预期的那样受到嘲笑,一切都正常工作。

但是,当我试图运行jUnit从Jenkins使用maven构建,我得到以下错误:-

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Misplaced argument matcher detected here:

-> at uk.co.common.Test.createRestClientMock(Test.java:166)

You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
    when(mock.get(anyInt())).thenReturn(null);
    doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
    verify(mock).someMethod(contains("foo"))

Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
Mocking methods declared on non-public parent classes is not supported.

添加依赖项

<dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.0.13-beta</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-core</artifactId>
            <version>1.3</version>
            <scope>test</scope>
        </dependency>

共有2个答案

程天佑
2023-03-14

您的方法看起来是正确的,并且可以正确地独立运行。这意味着您的错误可能在作为同一Maven套件的一部分运行的另一个方法中。

Mockito匹配器并不是纯粹的功能:在幕后有一个ThreadLocal匹配器堆栈,用于下一次存根或验证调用。Mockito matcher调用添加到此堆栈并返回伪值。然而,Mockito无法非常仔细地监控这个堆栈,因为在测试结束之前,它无法分析或预测匹配器调用的使用是否正确,此时它没有抛出异常所需的控件。这意味着,当在同一个JVM中运行一系列基于Mockito的测试时,Matcher尤其容易受到测试污染。

当单独运行测试时,或者使用不同的套件运行程序(Maven vs Eclipse)时,测试工作正常。不幸的是你,Maven命令你的测试,所以损坏的测试在你上面发布的测试之前。请注意,“破碎的测试”仍然通过;它只是让Matcher堆栈处于不良状态,这会导致正确的测试失败。

要诊断您的问题,请使用MockitoJUnitRule初始化测试。它将自动处理@Mock/@Spy/@Captor初始化(替换MockitoAnnotations.initMocks(this)),重要的是,它将调用Mockito。在每次测试结束时验证mOckitoUsage()<如果匹配器堆栈为空或任何存根或验证调用不完整,code>validateMockitoUsage将引发异常;如果运气好的话,坏掉的测试将会失败,确保你正确的测试通过。

(如果你不能使用MockitoJUnitRule,请使用JUnit4运行程序MockitoJUnitRunner,它与MockitoJUnitRule相同,但不能与其他运行程序或规则一起使用。当然,你也可以直接调用validateMockitoUsage,如果你在JUnit3上,或者你需要确定方法(你误用了匹配器。)

如果您发现您的匹配器被误用,并希望更好地理解它,这可能是另一个SO问题的好主题。

宗政斌
2023-03-14

我也遇到了同样的问题,结果是因为maven-surefire插件试图使用JUnit3运行程序而不是JUnit4,导致@RunAnd(MockitoJUnitRunner.class)注释被忽略。有几个潜在的原因,例如:

>

  • 在类路径中同时包含JUnit3和JUnit4。

    使用不同于类路径中的选项。

    在我的例子中,我提升了一个现有的项目,用jUnit: jUnit替换了jUnit: junit-dep,却没有意识到我在pom中的肯定配置有jUnit: junit-dep。Eclipse忽略POM中的任何内容,并将默认创建JUnit4配置,因此在运行时所有测试都通过了...JUnit测试。

  •  类似资料:
    • 我希望在使用运行测试时,控制台尽可能安静,除非出现问题。再说一次,当我在Eclipse中编写测试时(换句话说,当我在Eclipse中运行单个junit测试时),它们可以非常详细。 因此,当我使用surefire运行所有测试时,我需要一种方法来拥有不同的log4j/logback设置,而不是在Eclipse中一个接一个地运行它们。有没有办法做到这一点?

    • 我正在使用m2eclipse。 我在pom中配置了jetty maven插件。正确使用xml。 当我试图通过CMD执行时,它工作得很好。没有错 而当我试图通过日蚀执行时, 我缺少一些Jetty-Eclipse配置。有人能对此提出建议吗? 如果你发现任何错误, MAVEN_OPTS="-XX: MaxPermsize=256M-Xmx512M-Xdebug-Xrunjdwp:传输=dt_socket

    • 我最近升级到了优胜美地,我的maven停止了工作。我想这是因为我的环境变量没有设置,所以我按照这篇文章创建了一个environment.plist文件。 通过launchd.conf设置环境变量在OS X Yosemite/El Capitan/MacOS Sierra中不再有效? 但是我仍然在for Maven中找不到命令,并且由于某种原因没有设置$PATH,其他的则设置了 mac-r4498:

    • 问题内容: 我刚刚在Eclipse上第一次安装了插件m2e。 我编写了一个简单的JUnit(版本4)测试。我可以从Eclipse中运行它,但不能从pom.xml中运行它(alt单击,运行方式,Maven测试)。我想我需要告诉Maven搜索该课程,但我只是不知道如何。 另外,我在groupId“ junit”中找不到JUnit 4:只有版本3.8.1可用。我真的需要为3.x版本而不是4+版本编写测试

    • 问题内容: 当我遇到这个问题在运行时获取Maven工件版本时,我一直在寻找如何从maven pom或清单中获取应用程序名称(工件ID)和版本。 当我打包项目时,上面的内容对我有用,但是当我尝试使用eclipse运行程序时,似乎什么也没用。我在构建时尝试使用.properties方法,因为我认为这与包无关,但仍然没有得到结果。如果有人对这个问题有想法或解决方案,将不胜感激。 我的最后一次尝试是在下面

    • 我最后一次尝试在下面。这会在打包时使用清单(这会起作用),并在Eclipse中运行时尝试获取.properties文件。