【问题标题】:Exception while using PowerMockito with static method使用带有静态方法的 PowerMockito 时出现异常
【发布时间】:2018-12-15 10:58:56
【问题描述】:

我想使用 PowerMockito 模拟一个静态方法,

public class DepedencyService {

    public static int getImportantValue() {
        return -4;
    }
}

public class Component {

    public int componentMethod() {
        return DepedencyService.getImportantValue();
    }
}

但它给了我一个例外。

import static org.testng.Assert.assertEquals;
import org.easymock.EasyMock;
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(DepedencyService.class)
public class ComponentTest {
    @Test
    public void testComponentMethod() {
        Component c = new Component();
        PowerMockito.mockStatic(DepedencyService.class);
        EasyMock.expect(DepedencyService.getImportantValue()).andReturn(1);
        assertEquals(1, c.componentMethod());
    }
}

例外:-

java.lang.IllegalStateException:没有最后一次调用模拟可用 org.easymock.EasyMock.getControlForLastCall(EasyMock.java:520) 在 org.easymock.EasyMock.expect(EasyMock.java:498)

谁能帮帮我?为什么会失败?我是 PowerMockito 的新手,不知道在这里做什么!

【问题讨论】:

    标签: java unit-testing junit mockito powermockito


    【解决方案1】:

    您的主要问题是您正在编写 STUPID code(就像我们大多数人在开始时所做的那样),而您应该编写 SOLID 代码。

    使用 Powermock 只是对这种糟糕设计的投降。

    是的,只有static 方法的类称为实用程序类

    但是您应该克服这种误解,即提供通用行为的类应该(仅)具有static 方法。

    根据经验,整个程序中应该只有一个非私有static 方法,即main()

    【讨论】:

    • @Sunny 至少你可以围绕这个遗留代码编写一个简单的(= 太简单而不能失败 = 不需要测试)WrapperClass,并使用该包装器和你的新代码进行测试。
    • 好吧,这是我能做的。但我见过诸如 IOUtils.java 之类的实用程序类......所以如果你说的是终极真理,那么为什么开发人员要创建这样的类?
    • @Sunny “所以如果你说的是终极真理,那么为什么开发人员要创建这样的类?” 开发人员是人类,和所有其他人一样,他们会做一些愚蠢的事情出于很多原因。而且由于我也是人类,我不持有“终极真理”,我只是分享让我的开发人员生活更轻松的原因。
    【解决方案2】:

    您似乎在混合模拟框架。

    在进行测试之前,您需要正确安排静态依赖项

    由于 PowerMockito 用于模拟静态类,那么您应该使用 Mockito 来安排预期的行为

    例如

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(DepedencyService.class)
    public class ComponentTest {
        @Test
        public void testComponentMethod() {
            //Arrange        
            int expected = 1;
            PowerMockito.mockStatic(DepedencyService.class);
            Mockito.when(DepedencyService.getImportantValue()).thenReturn(expected);
            Component subject = new Component();
    
            //Act
            int actual = subject.componentMethod();
    
            //Assert
            assertEquals(expected, actual);
        }
    }
    

    也就是说,我建议不要让您的代码与静态依赖项紧密耦合。这使得测试代码变得困难。

    【讨论】:

    • 我明白,但它是一个实用程序类,所以我将其中的方法设为静态。
    猜你喜欢
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多