首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Mockito/Powermock模拟枚举单例类?

如何使用Mockito/Powermock模拟枚举单例类?
EN

Stack Overflow用户
提问于 2013-04-11 08:51:25
回答 4查看 38K关注 0票数 27

我不确定如何模拟枚举单例类。

代码语言:javascript
复制
public enum SingletonObject{
  INSTANCE;
  private int num;

  protected setNum(int num) {
    this.num = num;
  }

  public int getNum() {
    return num;
  }

我想在上面的例子中存根getNum(),但是我不知道如何模拟实际的SingletonObject类。我认为使用Powermock来准备测试会有所帮助,因为枚举本质上是最终的。

代码语言:javascript
复制
//... rest of test code
@Test
public void test() {
  PowerMockito.mock(SingletonObject.class);
  when(SingletonObject.INSTANCE.getNum()).thenReturn(1); //does not work
}

这是使用PowerMockMockito 1.4.10和Mockito 1.8.5。

EN

回答 4

Stack Overflow用户

发布于 2013-05-23 03:26:36

如果你想存根出实例返回的内容,你可以这样做,但这有点麻烦(使用反射和字节码操作)。我使用PowerMock 1.4.12 / Mockito 1.9.0创建并测试了一个包含三个类的简单项目。所有的类都在同一个包中。

SingletonObject.java

代码语言:javascript
复制
public enum SingletonObject {
    INSTANCE;
    private int num;

    protected void setNum(int num) {
        this.num = num;
    }

    public int getNum() {
        return num;
    }
}

SingletonConsumer.java

代码语言:javascript
复制
public class SingletonConsumer {
    public String consumeSingletonObject() {
        return String.valueOf(SingletonObject.INSTANCE.getNum());
    }
}

SingletonConsumerTest.java

代码语言:javascript
复制
import static org.junit.Assert.*;
import static org.powermock.api.mockito.PowerMockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;

@RunWith(PowerMockRunner.class)
@PrepareForTest({SingletonObject.class})
public class SingletonConsumerTest {
    @Test
    public void testConsumeSingletonObject() throws Exception {
        SingletonObject mockInstance = mock(SingletonObject.class);
        Whitebox.setInternalState(SingletonObject.class, "INSTANCE", mockInstance);

        when(mockInstance.getNum()).thenReturn(42);

        assertEquals("42", new SingletonConsumer().consumeSingletonObject());
    }
}

Whitebox.setInternalState的调用将INSTANCE替换为您可以在测试中操作的模拟对象。

票数 32
EN

Stack Overflow用户

发布于 2019-05-05 02:52:27

具有与您打算模拟的方法的接口

代码语言:javascript
复制
public interface SingletonInterface {
  int getNum();
}

让枚举实现接口

代码语言:javascript
复制
public enum SingletonObject implements SingletonInterface {
    INSTANCE;
    private int num;

    protected void setNum(int num) {
        this.num = num;
    }

    @Override
    public int getNum() {
        return num;
    }
}

模拟接口

代码语言:javascript
复制
@Test
public void test() {
  SingletonInterface singleton = Mockito.mock(SingletonInterface.class);
  when(singleton.getNum()).thenReturn(1); //does work
}
票数 1
EN

Stack Overflow用户

发布于 2020-06-15 20:24:08

除了上面Matt Lachman回答之外,在SingleTonConsumerTest.class中为power模拟创建一个对象工厂

代码语言:javascript
复制
@ObjectFactory
public IObjectFactory getObjectFactory() {
    return new org.powermock.modules.testng.PowerMockObjectFactory();
}

这将删除Mockito cannot mock/spy following: - final classes - anonymous classes - primitive types错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15939023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档