PowerMockito验证时间总是过去

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PowerMockito验证时间总是过去相关的知识,希望对你有一定的参考价值。

我试图使用Powermockiti.verify(mockObj, times(1))来确定一次静态void方法被调用,但即使我将times()的值更改为任何其他数字它仍然通过。

//要测试的类:

package nl.naturalis.nba.etl;

public class Person { 
  public static void someVoidMethod() {
    System.out.println("someVoidMethod Called");
  }
}

//测试类:

/** * */

package com.test.using.mockito

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.atMost;
import org.powermock.api.mockito.PowerMockito;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Person.class)
@PowerMockIgnore("javax.management.*")
@SuppressWarnings({"static-method"})
public class PersonTest {

  /**
   * @throws java.lang.Exception
   */
  @Before
  public void setUp() throws Exception {}

  /**
   * @throws java.lang.Exception
   */
  @After
  public void tearDown() throws Exception {}

  /**
   * Test method for {@link nl.naturalis.nba.etl.Person#someVoidMethod()}.
   */
  @Test
  public void testSomeVoidMethod() {

/*    Person person = Mockito.mock(Person.class);

    person.someVoidMethod();    
    Mockito.verify(person, times(1));
    person.someVoidMethod();*/

   PowerMockito.mock(Person.class);
   Person.someVoidMethod();
   PowerMockito.verifyStatic(Person.class,times(6));
   Person.someVoidMethod();

  }
}

现在,即使我将时间值更改为2或任何更高的值,它仍然会通过。

无论我放在Mockito.times()的价值,它总是通过

   Person.someVoidMethod();
   PowerMockito.verifyStatic(Person.class,times(6));
   Person.someVoidMethod();

我也尝试使用VerificationModeFactory.times(6)而不是Mockito.times(6),但实际上没有任何区别。

答案

没有更多细节我会说可能的解释是someVoidMethod是一种静态方法。如果是,大多数IDE会在您通过实例访问它的行上给出警告。

Mockito的工作原理是根据传入的类创建动态代理。对象上的方法将替换为执行验证,设置等的方法。但是,当您调用静态方法时,它不会通过实例。编译器替换任何看起来像这样的调用:

ClassForTest classForTest = mock(ClassForTest.class);
verify(classForTest).someVoidMethod("foo");

进入:

ClassForTest classForTest = mock(ClassForTest.class);
verify(classForTest);
ClassForTest.someVoidMethod("foo");

因此完全绕过Mockito代码(包括验证)。

一些模拟库,如PowerMock,允许您替换静态方法。然而,Mockito并不是因为在大多数情况下它会鼓励糟糕的设计:https://github.com/mockito/mockito/issues/1013

另一答案

愚蠢的我..我没注意到我使用的是PowerMockito.mock()而不是PowerMockito.mockStatic()。现在它正常工作:

  @Test
  public void testSomeVoidMethod() {

   PowerMockito.mockStatic(Person.class);

   Person.someVoidMethod();
   PowerMockito.verifyStatic(Person.class,Mockito.times(6));
   Person.someVoidMethod();


  }

}

以上是关于PowerMockito验证时间总是过去的主要内容,如果未能解决你的问题,请参考以下文章

在片段活动中显示自定义对话框

Laravel 5.3 + Passport:总是未经身份验证的错误

Android SMS Verification API 结果码始终为 0

使用PowerMockito.whennew的时候,注解preparefortest里面的类需要是mock的new代码所在的类的对象

PowerMockito 模拟单个静态方法并返回对象

C++ 代码片段执行