从类中声明的私有静态变量调用模拟静态方法

时间:2019-08-29 09:21:14

标签: junit mockito powermockito

从类中声明的私有静态变量调用的静态方法。

public class User{
   private static int refresh = readConfig();

   public static int readConfig(){
     // db call
   }
}

我尝试使用powermockito模拟readConfig方法,但是它不起作用。我需要在加载类时模拟readConfig()。

PowerMockito.mockStatic(User.class);
PowerMockito.when(User.readConfig()).thenReturn(1);

请让我知道如何模拟readConfig方法。

2 个答案:

答案 0 :(得分:2)

虽然您无法模拟与static块相关的任何内容,
您可以通过用SuppressStaticInitializationFor注释测试来告诉PowerMockito取消它。

请注意,这样做不会执行readConfig()方法,并且您的refresh变量将保留其默认值(在这种情况下为0)。

但是,这对您似乎并不重要,因为-根据您的评论-您主要尝试抑制相关的数据库错误。由于变量是私有变量,因此您(必须)模拟所有相关方法,因此不太可能在测试期间使用。

如果您需要将Reflections设置为特定值,则有疑问。

package test;

import org.junit.Assert;
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.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;

class User {
   protected static int refresh = readConfig();

   public static int readConfig(){
       return -1;
   }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticTest.class)
@SuppressStaticInitializationFor({"test.User"})
public class StaticTest {

    @Test
    public void test() throws Exception {

        PowerMockito.mockStatic(User.class);
        PowerMockito.when(User.readConfig()).thenReturn(42);

        Assert.assertEquals(0, User.refresh);
        Assert.assertEquals(42, User.readConfig());
    }
}

答案 1 :(得分:0)

模拟从最终静态变量调用的静态方法也有同样的问题。 假设我们有这个类:

class Example {

public static final String name = "Example " + Post.getString();

   .
   .
   .
}

所以我需要类 Post 的模拟静态方法 getString()。这应该在类加载时完成。

我发现的最简单的方法:

@BeforeClass
public static void setUpBeforeClass()
{
    PowerMockito.mockStatic(Post.class);
    PowerMockito.when(Post.getString(anyString(), anyString())).thenReturn("");
}

以及我在测试类顶部的注释:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Post.class)
@PowerMockIgnore({"jdk.internal.reflect.*", "javax.management.*"})