当前位置: 首页 > 知识库问答 >
问题:

使用Mockito设置私有final static内联变量的值

屠盛
2023-03-14

我试图测试一个方法,该方法调用另一个方法,该方法使用私有的final static变量进行内联初始化。然后,我尝试在测试运行时更改变量的值。我一直在尝试spring反射或为特定字段添加setter,但也许我应该使用powermock,这是我以前从未使用过的。我正独自尝试实现这一点,没有人问,所以,如果我能就什么是最好的方式进行一些指导,请。

使现代化

根据我在这里得到的一些反馈,模拟私有final变量可能不是我在测试中应该做的事情。我在这里打开了另一个问题,模拟cookie的返回值。使用Mockito获取值()

@Service
public class CookieSessionUtils {

private static final String VIADUCT_LOCAL_AMP = "viaductLocalAmp"; // Value to be changed when the test runs to test the "if Y" scenario.


public boolean verifyState(HttpServletRequest request, String state) {

    String viaductLocalAmp = getCookieByName(request, VIADUCT_LOCAL_AMP); 

    if (viaductLocalAmp.equalsIgnoreCase("Y")) {
        return true;
    }

    return false;
}

public String getCookieByName(HttpServletRequest request, String cookieName) {
    try {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(cookieName)) {
                    return cookie.getValue();
                }
            }
        }
    } catch (Exception e) {
        ExceptionLogger.logDetailedError("CookieSessionUtils.getCookieByName", e);
        log.error("Error on Cookie " + e.getMessage());
    }
    return "";
}

以下是我尝试过的几件事:

@Autowired
private CookieSessionUtils cookieSessionUtils;

@Mock
private HttpServletRequest request;

@Test
public void testVerifyState() {

    Cookie mockCookie = Mockito.mock(Cookie.class);
    Mockito.when(mockCookie.getName()).thenReturn("YviaductLocalAmp");

    Mockito.when(request.getCookies()).thenReturn(new Cookie[]{mockCookie});

//  cookieSessionUtils.setViaductLocalAmp("YviaductLocalAmp");

//  setField(cookieSessionUtils, "VIADUCT_LOCAL_AMP", VIADUCT_LOCAL_AMP);

//  Mockito.when(cookieSessionUtils.getCookieByName(request, "YviaductLocalAmp")).thenReturn("Y");

    assertTrue(cookieSessionUtils.verifyState(httpServletRequest, "viaductLocalAmp"));

}

非常感谢。

共有2个答案

蓝飞
2023-03-14

您试图违反信息隐藏/封装原则,因为您试图“测试代码”。


单元测试验证公共可观察行为,即:返回值和与依赖项的通信。

该常量的实际内容是测试不应该关心的实现细节。

因此,您真正应该测试的是,如果请求包含名为“viaductLocalAmp”且值为“Y”的cookie,则verifyState()返回true

牛智志
2023-03-14

不确定即使是Powermock也能帮忙。

建议的方法是不要使用内联常量,这些常量在测试时需要更改。

  • 如果你想改变这一点,你需要引入一个接口,在它之间提供常量。对实际源代码使用一个实现,对测试使用一个实现。在测试时切换实现。

如果您不想改变这一点,您可以尝试以下反射方法

  • 使字段可访问。
  • 删除最后的修饰符
  • 编辑字段值

我从这次讨论中得到了这个建议

private static void setFinalStatic(Field field, Object newValue) throws Exception {
   Field field = ClassWhereToMockStaticFinalVar.class.getDeclaredField("FieldName");   
   field.setAccessible(true);
 
   // remove final modifier from field
   Field modifiersField = Field.class.getDeclaredField("modifiers");
   modifiersField.setAccessible(true);
   modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
   field.set(null, newValue);
}
 类似资料:
  • 有没有可能的方法来模拟一个私人的最终场? 提前谢谢你们。

  • JavaScript中私有变量的使用 JavaScript中没有私有成员的概念;对象属性是公有的。但JavaSctipt中有个私有变量的概念: 任何在函数内部定义的变量都可以认为是私有变量,它只在这个函数内部有效,不能通过外部函数来访问。私有变量大概有:函数参数、局部变量和函数中嵌套的函数。 function add (num1, sum2) { var sum = num1 + num2

  • 严格来讲,JavaScript 中没有私有成员的概念;所有对象属性都是公有的。不过,倒是有一个私有变量的概念。任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问这些变量。私有变量包括函数的参数、局部变量和在函数内部定义的其他函数。来看下面的例子: function add(num1, num2){ var sum = num1 + num2; return su

  • 问题内容: 我刚刚开始自学Python,此脚本需要一些帮助: 我想得到它。 问题答案: 你快到了。您正在尝试修改全局变量,因此必须添加以下语句: 如果运行以下版本,则会看到您的版本中发生了什么: 输出: 运行它的方法,最终尝试在中修改函数的局部变量,这基本上是未定义的行为。请参阅文档中的警告: 注意: 默认 本地语言的 行为如以下功能所述:不应尝试对默认 本地 字典进行修改。如果需要在函数返回后查

  • 问题内容: 我有一个简单的方法返回一个。 它还创建了一个本地。我想测试添加到本地的值。 这是一个例子 将新增至本地时,如何测试? 问题答案: 这不是那么容易。 您需要使用powermock之类的东西。 使用powermock可以在调用方法并进行播放之前创建一个场景,这意味着您可以告诉类构造函数预期被调用并返回a 而不是real 。 这将允许您在上断言。 这样的事情应该起作用: 因此,当您的方法创建

  • #include <stdio.h> int func(void) { int i = 2; return i; } int main(void) { int a = 0; a = func(); printf("%d\n", a); return 0; } 技巧 在gdb中,可以用“set var variable=expr”命令设置变量