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

Mock static method called from private static variable declared in class

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

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

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

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

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

请告诉我如何模拟 readConfig 方法。

虽然您无法模拟与 static 块相关的任何内容,
你可以告诉 PowerMockito 通过用 SuppressStaticInitializationFor.

注释你的测试来抑制它

请注意,这样做不会执行 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());
    }
}

在模拟从最终静态变量调用的静态方法时遇到了同样的问题。 假设我们有这个 class:

class Example {

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

   .
   .
   .
}

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

所以我发现的最简单的方法是:

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

还有我在测试之上的注释class:

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