无法使用PowerMock覆盖最终类的静态最终变量

时间:2018-02-19 16:27:50

标签: java android unit-testing powermock powermockito

我尝试使用PowerMock Whitebox setInternalState api来覆盖最终类的静态最终变量。但它似乎并没有起作用。请参阅以下示例代码:

具有静态最终变量的最终类:

public final class BuildConfig {
    public static final String BUILD_TYPE = "debug";
}

返回上述变量的辅助类:

public class BuildConfigHelperClass {
    public String getBuildType() {
        return BuildConfig.BUILD_TYPE;
    }
}

测试类



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

import static org.junit.Assert.*;
import static org.powermock.api.mockito.PowerMockito.mockStatic;

@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("BuildConfig")
@PrepareForTest({BuildConfigHelperClassTest.class, BuildConfigHelperClass.class, BuildConfig.class})
public class BuildConfigHelperClassTest {

    private BuildConfigHelperClass subject;

    @Before
    public void setUp() {
        subject = new BuildConfigHelperClass();
    }

    @Test
    public void shouldReturnDebugBuildType() {
        assertEquals("debug", subject.getBuildType());
    }

    @Test
    public void shouldReturnProductionBuildType() {
        mockStatic(BuildConfig.class);
        Whitebox.setInternalState(BuildConfig.class, "BUILD_TYPE", "production");
        assertEquals("production", subject.getBuildType());
    }
}




在上面的测试类中,对于第二个测试subject.getBuildType()方法应返回" production"因为我通过Whitebox重写它,但它总是因为返回值而失败,即" debug"。

任何人都可以指导我找不到的东西。

1 个答案:

答案 0 :(得分:1)

编译器正在优化代码,其中包括:

public class BuildConfigHelperClass {
    public String getBuildType() {
         return BuildConfig.BUILD_TYPE;
   }
}

基本上编译为:

public class BuildConfigHelperClass {
    public String getBuildType() {
         return "debug";
   }
}

所以单元测试是针对没有引用BuildConfig的编译代码运行的。

不要直接引用BUILD_TYPE,而是尝试添加静态getter:

public final class BuildConfig {
    private static final String BUILD_TYPE = "debug";

    public static final String getBuildType() {
        return BUILD_TYPE;
    }
}

然后可以模拟静态方法:

@Test
public void shouldReturnProductionBuildType() {
    mockStatic(BuildConfig.class);
    // Whitebox.setInternalState(BuildConfig.class, "BUILD_TYPE", "production");
    PowerMockito.when(BuildConfig.getBuildType()).thenReturn("production");
    assertEquals("production", subject.getBuildType());
}

这个测试适用于我的本地,虽然其他编译器可能仍然可以优化它并打破测试。