Java 如何使用Mockito/Powermock模拟枚举单例类?
我不确定如何模拟枚举单例类Java 如何使用Mockito/Powermock模拟枚举单例类?,java,enums,singleton,mockito,powermock,Java,Enums,Singleton,Mockito,Powermock,我不确定如何模拟枚举单例类 public enum SingletonObject{ INSTANCE; private int num; protected setNum(int num) { this.num = num; } public int getNum() { return num; } 我想在上面的示例中使用stub getNum(),但我不知道如何模拟实际的SingletonObject类。我认为使用Powermock来准备测试会有
public enum SingletonObject{
INSTANCE;
private int num;
protected setNum(int num) {
this.num = num;
}
public int getNum() {
return num;
}
我想在上面的示例中使用stub getNum(),但我不知道如何模拟实际的SingletonObject类。我认为使用Powermock来准备测试会有所帮助,因为枚举本身就是最终的
//... rest of test code
@Test
public void test() {
PowerMockito.mock(SingletonObject.class);
when(SingletonObject.INSTANCE.getNum()).thenReturn(1); //does not work
}
这是在使用PowerMockito 1.4.10和Mockito 1.8.5。如果您想删除实例返回的内容,可以这样做,但这有点麻烦(使用反射和字节码操作)。我使用PowerMock 1.4.12/Mockito 1.9.0创建并测试了一个包含三个类的简单项目。所有课程都在同一个包中 SingletonObject.java SingletonConsumer.java SingletonConsumerTest.java
对
白盒.setInternalState
的调用将实例
替换为可在测试中操作的模拟对象。与要模拟的方法有接口
public interface SingletonInterface {
int getNum();
}
让枚举实现接口
public enum SingletonObject implements SingletonInterface {
INSTANCE;
private int num;
protected void setNum(int num) {
this.num = num;
}
@Override
public int getNum() {
return num;
}
}
@Test
public void test() {
SingletonInterface singleton = Mockito.mock(SingletonInterface.class);
when(singleton.getNum()).thenReturn(1); //does work
}
模拟接口
public enum SingletonObject implements SingletonInterface {
INSTANCE;
private int num;
protected void setNum(int num) {
this.num = num;
}
@Override
public int getNum() {
return num;
}
}
@Test
public void test() {
SingletonInterface singleton = Mockito.mock(SingletonInterface.class);
when(singleton.getNum()).thenReturn(1); //does work
}
除了上面的Matt Lachman答案之外,在
SingleTonConsumerTest.class
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new org.powermock.modules.testng.PowerMockObjectFactory();
}
这将删除以下内容:-最终类-匿名类-基元类型错误。我不确定这是否是最好的方法,但在我的情况下,到目前为止它工作正常。我使用mockito内核和mockito内联(3.11.0),我在spy的帮助下模拟我的单例。以您的班级为例:
SingletonObject so = SingletonObject.INSTANCE;
private SingletonObject spySo = Mockito.spy(so);
@Before
public void setUp() {
Mockito.doReturn(10).when(spySo).getNum();
}
@Test
public void simpleTest() {
assertThat(spySo.getNum(), is(10));
}
检查类似的线程:谢谢Martin,我通读了该线程,它看起来是一种使用非枚举方式实现单例的方法,我能够正确地使用该方法进行模拟。但是,有没有办法模拟枚举单例类?据我所知,enum singleton类是在java 1.5之后声明singleton的推荐方法。singleton是邪恶的:)但是如何模拟SingletonObject.class呢?它会给MockitoException加上注释“Mockito不能模仿/刺探以下:-最终类-匿名类-基本类型”这使用了PowerMock。嗨,我得到了
java.lang.IllegalAccessException:Can not set static final
,而使用Whitebox.setInternalState
。你知道为什么吗?你在你的测试类上使用了@PrepareForTest
注释吗?我尝试了同样的方法,但是我的枚举构造函数仍然在执行,我不想这样。上面的解决方案也模拟枚举的构造函数吗?这个答案是最好的
SingletonObject so = SingletonObject.INSTANCE;
private SingletonObject spySo = Mockito.spy(so);
@Before
public void setUp() {
Mockito.doReturn(10).when(spySo).getNum();
}
@Test
public void simpleTest() {
assertThat(spySo.getNum(), is(10));
}