doNothing() 方法正在调用实际方法

doNothing() method is calling actual method

我正在尝试在调用最终无效方法时执行 doNothing(),但 doNothing() 调用调用的是实际方法。

SwitchWorker class

public class SwitchWorker {

    public boolean switchMethod(String id){
        this.methodA(id);
        return true;
    }

    public void methodA(String id){
        final Switch switchObj = Switch.getSwitchInstance(); 
        switchObj.finalVoidMethod(id);
        // XYZ......
    }
}

切换Class

public final class Switch {
    private static final Switch INSTANCE = new Switch();
    private Switch() { //Private Constructor
        super();
    }
    public static Switch getSwitchInstance() {
        return INSTANCE;
    }
    public final synchronized void finalVoidMethod(String param) {
        // Do Something
    }    
}

测试代码:

 @RunWith(PowerMockRunner.class)
 @SuppressStaticInitializationFor("com.application.switching.Switch")
 public class SwitchWorkerTest {

        @Test
        public void test() throws Exception {
            SwitchWorker swObj = new SwitchWorker();

            final String channelId = "0001";

            Switch switchMock = mock(Switch.class);
            PowerMockito.mockStatic(Switch.class);
            when(Switch.getSwitchInstance()).thenReturn(switchMock);

            doNothing().when(switchMock).finalVoidMethod(channelId);

            boolean result = swObj.switchMethod(channelId);
            assertTrue(result);                            
        }

我是否遗漏了 doNothing() 方法的任何内容?

"doNothing().when(switchMock).finalVoidMethod(channelId);"

doNothing() 正在调用实际的 finalVoidMethod() 而不是模拟。但是,switchMock 是一个 Mocked 对象。

我已经查看了关于 PowerMockito、模拟静态方法和 doNothing 方法的堆栈溢出的几乎所有问题,我不确定我是否遗漏了任何内容,因为我已经按照大多数示例来构建代码。我也添加了 @PrepareForTest 但后来将其删除。

谢谢。

编辑:我将代码剪短得更抽象,并稍作改动以适应@kswaughs 评论

public boolean mockedMethod(final String input) {
    System.out.println("0----------------------");
    final Switch switchObj = Switch.getSwitchInstance();
    System.out.println("1:switchObj: "+ switchObj);
    switches.refresh("input");
    System.out.println("2----------------------");
    return true;
}

附测试码:

@RunWith(PowerMockRunner.class)
@PrepareForTest({Switch.class, SwitchWorker.class})
public class SwitchWorkerTest {
    @Test
    public void test() throws Exception {
        SwitchWorker swObj = new SwitchWorker();

        Switch switchMock = mock(Switch.class);
        PowerMockito.mockStatic(Switch.class);
        when(Switch.getSwitchInstance()).thenReturn(switchMock);
        boolean result = swObj.mockedMethod("0001");
        assertTrue(result); 

returns。

0----------------------
1:switchObj: Mock for Switch, hashCode: 1659309731

java.lang.NullPointerException
at com.application.switching.Switch.refresh(Switch.java:238)
at com.application.switching.SwitchWorker.run(SwitchWorker.java:51)

我 运行 你的例子,它对我来说工作正常。这里要记住两件事。

  1. 当你模拟一个对象时,模拟对象的方法将不会被执行,默认情况下 returns null 如果它们有任何 return 类型。对于 void 方法,您不必明确设置期望值。

  2. 要模拟最终的 class,您必须在 prepareForTest 中声明它。

请检查您是否拥有 mockito 和 powermockito 的兼容版本。

我运行你的例子如下。

Maven

 <dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-junit4</artifactId>
  <version>1.6.6</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-api-mockito</artifactId>
  <version>1.6.6</version>
  <scope>test</scope>
</dependency>

测试代码

package com.kswaughs;

import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Switch.class)
public class SwitchWorkerTest {

   @Test
   public void test() throws Exception {
       SwitchWorker swObj = new SwitchWorker();

       final String channelId = "0001";

       Switch switchMock = mock(Switch.class);
       PowerMockito.mockStatic(Switch.class);
       when(Switch.getSwitchInstance()).thenReturn(switchMock);

       boolean result = swObj.switchMethod(channelId);
       Assert. assertTrue(result);                            
   }
}

在将所有方法更改为使用 PowerMockito 之后,我意识到模拟对象本身是使用 Mockito 初始化的。

变化中:

Switch switchMock = mock(Switch.class);

到(或更改导入):

Switch switchMock = PowerMockito.mock(Switch.class);

解决了我的问题。

感谢贡献的人(像这样的小东西是我的祸根)

doNothing() 方法会调用实际的方法,如果你不想调用,你可以使用 suppress-method。它会抑制 no-return 方法的调用。

doNothing().when(switchMock).finalVoidMethod(channelId);

改变

suppress(method(SwitchWorker.class, "finalVoidMethod"));