Powermock 无法模拟静态 class
Powermock can't mock static class
我有一个 class,其代码类似于:
public class class1{
private static final ConfigurationService config = Util.getInstance(ConfigurationService.class);
private SendQueueMessages sender;
public void start() throws LifecycleException{
LOGGER.info("Starting");
final ActiveMq activemq = config.getConfiguration().getActiveMq();
sender = new SendQueueMessages(activemq.getQueueName());
}
}
在程序的其他地方,Guice 被用来绑定配置服务和 Util,如下所示:
Util.register(new ThingICantChange(){
@Override
protected void configure (){
super.configure();
bind(ConfigurationService.class).to(ConfigurationServiceImpl.class).asEagerSingleton();
}
});
这可以进行单元测试吗?我最初尝试使用 JUnit 5 和 mockito,但很明显我需要模拟静态 classes/methods (IoCUtils) 并切换到 JUnit4 for PowerMock。
我试过:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Util.class)
public class Class1Test{
@Test
public void canStart(){
mockStatic(Util.class);
when(Util.getInstance(ConfigurationService.class)).thenReturn(new ConfigurationService);
Class1 class = new Class1();
class.start();
//etc.
}
}
然而,这只是给我一个关于 Util not prepared for test 的错误。将 mockStatic() 更改为 PowerMockito.spy() 确实让我明白了,但随后抛出了一个空指针错误。
我找到了解决方案,尽管我对此有不同的看法。
使用 Util.register(第二个代码块)我注册了一个创建模拟对象的配置服务实现。这行得通,让我测试了 start() 方法,但感觉有点违背单元测试的想法。
public class ConfigServiceTest implements ConfigurationService{
@Override
public Configuration getConfiguration() {
Configuration conf = mock(Configuration.class);
ActiveMq amq = mock(ActiveMq.class);
when(amq.getQueueName()).thenReturn("test");
when(amq.getBrokerUrl()).thenReturn("http://127.0.0.1:61616?soTimeout=1000");
when(conf.getActiveMq()).thenReturn(amq);
return conf;
}
//other methods just allowed to return null
}
然后在测试中:
Util.register(new thingICantChange(){
@Override
protected void configure (){
super.configure();
bind(ConfigurationService.class).to(ConfigServiceTest.class).asEagerSingleton();
}
});
class1 service = new class1();
service.start();
Assert.assertEquals(true, true);
开始是无效的,而不是一个新线程,所以 Assert.assertEquals(true,true) 是我周围的人知道的最好的检查开始 运行。 Mockito/PowerMock times(1) 需要模拟 class1,这似乎与单元测试相反,看它是否可以 运行.
我有一个 class,其代码类似于:
public class class1{
private static final ConfigurationService config = Util.getInstance(ConfigurationService.class);
private SendQueueMessages sender;
public void start() throws LifecycleException{
LOGGER.info("Starting");
final ActiveMq activemq = config.getConfiguration().getActiveMq();
sender = new SendQueueMessages(activemq.getQueueName());
}
}
在程序的其他地方,Guice 被用来绑定配置服务和 Util,如下所示:
Util.register(new ThingICantChange(){
@Override
protected void configure (){
super.configure();
bind(ConfigurationService.class).to(ConfigurationServiceImpl.class).asEagerSingleton();
}
});
这可以进行单元测试吗?我最初尝试使用 JUnit 5 和 mockito,但很明显我需要模拟静态 classes/methods (IoCUtils) 并切换到 JUnit4 for PowerMock。
我试过:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Util.class)
public class Class1Test{
@Test
public void canStart(){
mockStatic(Util.class);
when(Util.getInstance(ConfigurationService.class)).thenReturn(new ConfigurationService);
Class1 class = new Class1();
class.start();
//etc.
}
}
然而,这只是给我一个关于 Util not prepared for test 的错误。将 mockStatic() 更改为 PowerMockito.spy() 确实让我明白了,但随后抛出了一个空指针错误。
我找到了解决方案,尽管我对此有不同的看法。
使用 Util.register(第二个代码块)我注册了一个创建模拟对象的配置服务实现。这行得通,让我测试了 start() 方法,但感觉有点违背单元测试的想法。
public class ConfigServiceTest implements ConfigurationService{
@Override
public Configuration getConfiguration() {
Configuration conf = mock(Configuration.class);
ActiveMq amq = mock(ActiveMq.class);
when(amq.getQueueName()).thenReturn("test");
when(amq.getBrokerUrl()).thenReturn("http://127.0.0.1:61616?soTimeout=1000");
when(conf.getActiveMq()).thenReturn(amq);
return conf;
}
//other methods just allowed to return null
}
然后在测试中:
Util.register(new thingICantChange(){
@Override
protected void configure (){
super.configure();
bind(ConfigurationService.class).to(ConfigServiceTest.class).asEagerSingleton();
}
});
class1 service = new class1();
service.start();
Assert.assertEquals(true, true);
开始是无效的,而不是一个新线程,所以 Assert.assertEquals(true,true) 是我周围的人知道的最好的检查开始 运行。 Mockito/PowerMock times(1) 需要模拟 class1,这似乎与单元测试相反,看它是否可以 运行.