简体   繁体   English

如何模拟在另一个类中使用另一个静态最终变量的变量

[英]How to mock a variable that uses another static final variable in another class

I am having a problem setting up this method under test in junit. 我在junit中测试中设置此方法时遇到问题。 I am trying to test the method to updateConfigDates with a new timestamp. 我正在尝试测试具有新时间戳记的updateConfigDates方法。 Please bear with me here, as there is a lot of information provided and it doesn't really look too pretty. 请在这里与我保持联系,因为这里提供了很多信息,而且看起来确实不太漂亮。

Here is the method under test. 这是被测试的方法。

public static Document updateConfigDates(Document doc, Timestamp configDate)
{
    //Format timestamp to string
    String configTimestampStr = GTR_DATE_FORMAT.format(configDate) + "Z";

    //Change configuration date for all nodes in GTR
    NodeList configIDNodes = doc.getElementsByTagName("ConfigDate");
    for (Element cidNode : new DOMUtil.ElementList(configIDNodes))
    {
        cidNode.setTextContent(configTimestampStr);
    }

    return doc;
}

The problem is on the line: 问题就在网上:

    //Format timestamp to string
    String configTimestampStr = GTR_DATE_FORMAT.format(configDate) + "Z";

Which is using a public final class Constants 这是使用公共最终类常量

public final class Constants
{
    /** GTR Timestamp formatter without micro-second */
    public static final FastDateFormat GTR_DATE_FORMAT 
                           = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss");
}

Here is my current test case 这是我当前的测试用例

@Test
public void testUpdateConfigDates() throws Exception
{
    // check if configDate in document is expected
    String docConfigDate = doc.getElementsByTagName("ConfigDate").item(0).getTextContent();
    assertEquals(docConfigDate, "2012-02-22T16:07:27Z");

    LOG.info("docConfigDate: " + docConfigDate);

    // variables
    Timestamp newConfigDate = Timestamp.valueOf("2009-07-29 13:24:11");

    // Mocking statics
    //PowerMockito.mockStatic(GTRConstants.class);

    // String configTimestampStr = GTR_DATE_FORMAT.format(configDate) + "Z";
    //common.setFinalStatic(GTRUtility.class.getDeclaredField("configTimestampStr"), "yyyy-MM-dd'T'HH:mm:ss" + "Z");
    common.setFinalStatic(Constants.class.getDeclaredField("GTR_DATE_FORMAT"), FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss"));

    /* setFinalStatic ExceptionInInitializerError information below
     * 
     * Field#set(Object, Object) can be used to set static fields.
     * If you try to set the field of an uninitialized class, the JVM will first try to initialize the class.
     * If a failure occurs, then set will throw a ExceptionInInitializerError.
     */

    // execute method under test
    doc = gtrUtility.updateConfigDates(doc, newConfigDate);

    // verify expectations
    docConfigDate = doc.getElementsByTagName("ConfigDate").item(0).getTextContent();
    assertEquals(docConfigDate, "2009-07-29 13:24:11");
}

Using a setFinalStatic solution posted here , which successfully works with some other tests I'm doing. 使用此处发布setFinalStatic解决方案 ,该解决方案可以成功地与我正在进行的其他测试一起使用。

public static void setFinalStatic(Field field, Object newValue) throws Exception
{
    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);
}

I have tried several solutions: 我尝试了几种解决方案:

  • My new and most recent method, using setFinalStatic method 我的最新方法,使用setFinalStatic方法
  • Mocking Constants result with PowerMockito and Mockito. 使用PowerMockito和Mockito产生模拟常量。
  • Mocking GTR_DATE_FORMAT instance with PowerMockito and Mockito. 使用PowerMockito和Mockito模拟GTR_DATE_FORMAT实例。
  • Mocking FastDateFormat with PowerMockito and Mockito. 使用PowerMockito和Mockito模拟FastDateFormat。

All of which have failed. 所有这些都失败了。 I think the setFinalStatic method is the closest, however I am currently getting error ExceptionInInitializerError (as also discussed from a user here and in Oracle Doc here ) 我认为setFinalStatic方法是最接近的方法,但是我目前遇到了ExceptionInInitializerError错误(也从此处的用户以及此处的Oracle Doc中进行了讨论

It turns out the answer to my problem was that the Constants file was executing some initialization methods (in this case: safeGetTypeId(x) on an object, from database) that I have to mock. 事实证明,对我的问题的答案是,Constants文件正在执行一些我必须模拟的初始化方法(在这种情况下:对来自数据库的对象的safeGetTypeId(x))。

I should have noticed this faster when realizing that updateObjectId hardcoded test was working and the updateTimestamp using the constants class GTR_DATE_FORMAT. 当意识到使用常量类GTR_DATE_FORMAT的updateObjectId硬编码测试正在运行并且updateTimestamp正常运行时,我应该注意到这一点。

The constructors were empty and I wasn't expecting anything else to be executed. 构造函数是空的,我没想到会执行其他任何操作。

This is kind of an extreme and complicated question, so I may delete this question, however if it could help somebody in the future I will leave it. 这是一个极端而复杂的问题,因此我可以删除此问题,但是如果将来可以帮助某个人,我将不予理会。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 PowerMockito:如何模拟最终的静态变量初始化 - PowerMockito: How to mock final static variable initialization 用另一个最终静态变量初始化最终静态变量时的内存消耗 - Memory consumption on Initializing final static variable with another final static 在模拟中初始化静态最终变量 - Initializing a static final variable in a mock 如何从另一个类访问静态变量? - How to access static variable from another class? 如何模拟静态方法设置的最终静态变量? - How to mock a final static variable that is being set by a static method? 更改另一个类中没有静态变量的变量? - Changing a variable in another class without a static variable? 如何在 Spock 的私有 static 最终变量中使用模拟? - How to use mock in a private static final variable in Spock? 如何使用JUnit,EasyMock或PowerMock模拟静态最终变量 - How to mock a static final variable using JUnit, EasyMock or PowerMock 如何模拟从测试类的另一种方法获得的局部变量? - How to mock local variable obtained from another method of tested class? 如何从另一个类的静态方法更改静态变量的值 - how to change the value of a static variable from a static method of another class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM