【问题标题】:Mock static method called from private static variable declared in class从类中声明的私有静态变量调用的模拟静态方法
【发布时间】:2019-08-29 09:21:14
【问题描述】:

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

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 方法。

【问题讨论】:

  • it is not working 是一个相当广泛的声明。它并没有像预期的那样告诉我们实际发生的事情。如果没有 minimal reproducible example 澄清您的具体问题或其他详细信息以准确突出所做的事情,就很难重现问题,从而更好地理解所询问的内容。
  • 在执行 PowerMockito.mockStatic(User.class) 时,它也在执行 readConfig 方法,并为与数据库语句相关的模拟提供错误。当时我们正在模拟 readConfig 类被调用。但在下一个声明中,我们正在嘲笑它。这就是为什么我明确提到我必须在类加载时模拟 readConfig()。

标签: junit mockito powermockito


【解决方案1】:

虽然您无法模拟与 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());
    }
}

【讨论】:

    【解决方案2】:

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

    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.*"})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多