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

抛出UnfinishedVerificationException(可能与本机方法调用有关)的Mockito

宓昂雄
2023-03-14

当我运行测试用例时,我有以下异常:

org.mockito.exceptions.misusing.UnfinishedVerificationException: 
Missing method call for verify(mock) here:
-> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Example of correct verification:
    verify(mock).doSomething()

Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.

    at com.bignibouX.tests.repository.member.MemberCachingIntegrationTest.testFindByEmail(MemberCachingIntegrationTest.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:81)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:215)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:81)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:161)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

测试用例有两个测试,如下所示:

@ActiveProfiles(Profiles.TEST)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { FullIntegrationTestConfiguration.class, BaseTestConfiguration.class, MemberCachingIntegrationTest.Config.class })
public class MemberCachingIntegrationTest {

    private static final Member MEMBER_ONE = new Member();
    private static final Member MEMBER_TWO = new Member();

    @Autowired
    private MemberRepository memberRepositoryMock;

    @After
    public void validate() {
        validateMockitoUsage();
    }

    @Test
    public void testFindByEmail() {
        when(memberRepositoryMock.findByEmail(anyString())).thenReturn(MEMBER_ONE, MEMBER_TWO);

        Member firstInvocation = memberRepositoryMock.findByEmail("foo@foo.com");
        assertThat(firstInvocation, is(MEMBER_ONE));

        Member secondInvocation = memberRepositoryMock.findByEmail("foo@foo.com");
        assertThat(secondInvocation, is(MEMBER_ONE));

        verify(memberRepositoryMock, times(1)).findByEmail("foo@foo.com");

        Member thirdInvocation = memberRepositoryMock.findByEmail("bar@bar.com");
        assertThat(thirdInvocation, is(MEMBER_TWO));

        verify(memberRepositoryMock, times(1)).findByEmail("bar@bar.com");
    }

    @Test
    public void passingInexistentEmailToSendPasswordResetShouldNotCauseNPE() {
        fail("MemberRepository's findByEmail throws NPE if email not found in db! Reason: because cache was set up not to allow null values...");
        fail("Appropriate error page not displayed when above NPE is thrown!");
    }

    @Profile(Profiles.TEST)
    @Configuration
    static class Config {

        @Bean
        public MemberRepository memberRepositoryMock() {
            return mock(MemberRepository.class);
        }
    }
}

我有两个问题:

    null
@RooJpaRepository(domainType = Member.class)
public interface MemberRepository {

    @Cacheable(value = CacheConfiguration.DATABASE_CACHE_NAME)
    Member findByEmail(String email);

    @Cacheable(CacheConfiguration.DATABASE_CACHE_NAME)
    Member findByToken(String token);

    @CacheEvict(value = CacheConfiguration.DATABASE_CACHE_NAME, key = "#result.email")
    <S extends Member> S save(S entity);
}

org.springframework.aop.framework.ProxyFactory: 2 interfaces [com.bignibou.repository.member.MemberRepository, org.mockito.cglib.proxy.Factory]; 1 advisors [org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor: advice bean 'null']; targetSource [SingletonTargetSource for target object [com.bignibou.repository.member.MemberRepository$$EnhancerByMockitoWithCGLIB$$1b543cbe@4cca9ed4]]; proxyTargetClass=false; optimize=false; opaque=false; exposeProxy=false; frozen=false
verify(memberRepositoryMock, times(1)).findByEmail("bar@bar.com");
@After
public void validate() {
        validateMockitoUsage();
}

测试毫无问题地通过了....

编辑4:实际上,我正在拼命地修改下面的示例:https://stackoverflow.com/a/24229350/536299,这是在另一篇文章中给我的。人们会注意到模拟是autowired的,测试确实使用了spring上下文。谁能帮我把考试考对吗?

共有1个答案

解高昂
2023-03-14

sun.reflect.nativeMethodAccessorImpl.invoke0(Native Method)-根据您提供的堆栈跟踪,mockito在报告错误时有点困惑。它实际上与您的问题无关,但无论如何,这是nativeMethodAccessorImpl.invoke0,它是本机的(请参见grep代码)。SpringJUnit4ClassRunner运行它,这是它的工作方式,您不应该关心它。

关于您真正的问题,正如我在评论中所写的,这是因为Spring将模拟对象包装成代理。如果添加

System.out.println(memberRepositoryMock.getClass());

您将在控制台中看到,它不是模拟,而是那里的某个代理。Mockito只能存根mock,所以这就是为什么您会重复这个错误。

@ActiveProfiles(Profiles.TEST)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { FullIntegrationTestConfiguration.class, BaseTestConfiguration.class, MemberCachingIntegrationTest.Config.class })
public class MemberCachingIntegrationTest {

    @Autowired
    private MemberRepository cachedRepository;

    @Autowired
    private MockProvider mockProvider;

    @After
    public void validate() {
        validateMockitoUsage();
    }

    @Test
    public void test() {
        when(mockProvider.get().findByEmail(anyString())).thenReturn("foo", "bar");

        String firstInvocation = cachedRepository.findByEmail("foo@foo.com");
        assertThat(firstInvocation, is("foo"));

        String secondInvocation = cachedRepository.findByEmail("foo@foo.com");
        assertThat(secondInvocation, is("foo"));

        verify(mockProvider.get(), times(1)).findByEmail("foo@foo.com");

        String thirdInvocation = cachedRepository.findByEmail("bar@bar.com");
        assertThat(thirdInvocation, is("bar"));

        verify(mockProvider.get(), times(1)).findByEmail("bar@bar.com");
    }

    @Configuration
    static class Config {

        private MemberRepository mockRepository = mock(MemberRepository.class);

        @Bean
        public MemberRepository cachedRepository() {
            return mockRepository;
        }

        @Bean
        public MockProvider mockProvider() {
            return new MockProvider(mockRepository);
        }

    }

    public static class MockProvider {

        private final MemberRepository repository;

        public MockProvider(MemberRepository repository) {
            this.repository = repository;
        }

        public MemberRepository get() {
            return this.repository;
        }

    }
}

注意:为了更清楚的例子,存储库返回字符串而不是成员

 类似资料:
  • 问题内容: TL; DR MatcherAPI 的设计决策是什么? 背景 Matcher有我意想不到的行为,而我找不到很好的理由。API文档说: 创建后,可以使用匹配器执行三种不同类型的匹配操作:这些方法中的每一个都返回一个指示成功或失败的布尔值。通过查询匹配器的状态,可以获得有关成功匹配的更多信息。 API文档进一步说明了: 匹配器的显式状态最初是不确定的。在成功匹配之前尝试查询它的任何部分都将

  • 已经为此挣扎了一个星期,没有成功。 只要我点击,整个应用程序崩溃。 03-25 14:58:35.731 274 6-4224/com.justanotherandroidapp.developme E/androidruntime:致命异常:AsyncTask#2进程:com.justanotherandroidapp.developm,PID:2746 java.lang.runtimeExc

  • 我在我的项目中使用了来自codebutler的android-websockets库。但是在执行方法时遇到了问题。代码如下: 05-11 17:58:19.873:W/System.err(29443):java.net.SocketException:套接字关闭 05-11 17:58:19.873:W/System.err(29443):at libcore.io.posix.recvFrom

  • DR 的API背后的设计决策是什么? 此代码引发一个 在。为了解决这个问题,有必要调用或其他方法,使进入允许的状态。以下作品: 在处添加对的调用,可将设置为调用的正确状态。

  • 问题内容: 编辑:到目前为止,所有建议的答案都没有奏效。 我正在用Django运行此呼叫。服务器第一次运行时,将返回“ n_usr”(这将更改用户文件的形式)。第二次,它只是抛出一个错误。 问题答案: 在中,您具有: 然后您有: 你得到,因为jQuery是试图序列为jQuery对象,而且它不能。它可能正在尝试调用字符串方法,并将其作为上下文传递给jQuery对象,从而导致错误。 您需要添加。

  • 问题内容: 我正在使用Mockito。我想在调用未存根方法时抛出一个。 有什么办法吗? 问题答案: 您可以为模拟设置默认答案。所有未存根的方法都将使用此默认答案。 请注意,您 不能 使用此功能,因为该方法是在方法调用之前(嘲笑when()调用如何工作的?),并且它将在模拟进入存根模式之前抛出a 。 因此,您必须使用它来工作。