Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我如何编写单元测试以确保基于日期/时间的代码适用于所有时区以及有/没有DST?_Java_Unit Testing_Timezone_Jodatime_Dst - Fatal编程技术网

Java 我如何编写单元测试以确保基于日期/时间的代码适用于所有时区以及有/没有DST?

Java 我如何编写单元测试以确保基于日期/时间的代码适用于所有时区以及有/没有DST?,java,unit-testing,timezone,jodatime,dst,Java,Unit Testing,Timezone,Jodatime,Dst,我正在使用JodaTime2.1,我正在寻找一个模式到单元测试代码,该代码执行日期/时间操作,以确保它在所有时区都表现良好,并且独立于时间 具体而言: 如何模拟系统时钟(这样我就不必模拟调用newdatetime()获取当前时间的所有位置) 如何对默认时区执行相同操作 单次试验的变更 DateTimeZone default; DateTimeZone testedTZ; @Before public void setUp() { default = GateTimeZone.ge

我正在使用JodaTime2.1,我正在寻找一个模式到单元测试代码,该代码执行日期/时间操作,以确保它在所有时区都表现良好,并且独立于时间

具体而言:

  • 如何模拟系统时钟(这样我就不必模拟调用
    newdatetime()
    获取当前时间的所有位置)
  • 如何对默认时区执行相同操作
  • 单次试验的变更

    DateTimeZone default;  
    
    DateTimeZone testedTZ;
    
    @Before
    public void setUp()
    {
       default = GateTimeZone.getDefault();
       DateTimeZone.setDefault
    }  
    
    @After
    public void tearDown()
    {
       default = GateTimeZone.setDefault();
       DateTimeZone.setDefault(testedTZ)
    }   
    
    @Test
    public void test()
    {
    //...
    }
    

    您可以为此使用
    @规则
    。以下是规则的代码:

    import org.joda.time.DateTimeZone;
    import org.junit.rules.TestWatcher;
    import org.junit.runner.Description;
    
    public class UTCRule extends TestWatcher {
    
        private DateTimeZone origDefault = DateTimeZone.getDefault();
    
        @Override
        protected void starting( Description description ) {
            DateTimeZone.setDefault( DateTimeZone.UTC );
        }
    
        @Override
        protected void finished( Description description ) {
            DateTimeZone.setDefault( origDefault );
        }
    }
    
    您可以使用如下规则:

    public class SomeTest {
    
        @Rule
        public UTCRule utcRule = new UTCRule();
    
        ....
    }
    
    这将在执行
    SomeTest
    中的每个测试之前将当前时区更改为UTC,并在每个测试之后恢复默认时区

    如果要检查多个时区,请使用如下规则:

    import org.joda.time.DateTimeZone;
    import org.junit.rules.TestWatcher;
    import org.junit.runner.Description;
    
    public class TZRule extends TestWatcher {
    
        private DateTimeZone origDefault = DateTimeZone.getDefault();
    
        private DateTimeZone tz;
    
        public TZRule( DateTimeZone tz ) {
            this.tz = tz;
        }
    
        @Override
        protected void starting( Description description ) {
            DateTimeZone.setDefault( tz );
        }
    
        @Override
        protected void finished( Description description ) {
            DateTimeZone.setDefault( origDefault );
        }
    }
    
    将所有受影响的测试放在抽象基类
    abstractztest
    中,并对其进行扩展:

    public class UTCTest extends AbstractTZTest {
        @Rule public TZRule tzRule = new TZRule( DateTimeZone.UTC );
    }
    
    将使用UTC执行
    AbstractTZTest
    中的所有测试。对于要测试的每个时区,您都需要另一个类:

    public class UTCTest extends AbstractTZTest {
        @Rule public TZRule tzRule = new TZRule( DateTimeZone.forID( "..." );
    }
    
    因为测试用例是继承的,所以您只需要定义规则

    以类似的方式,您可以改变系统时钟。使用调用
    DateTimeUtils.setCurrentMillisProvider(…)
    的规则来模拟测试在特定时间运行,并使用
    DateTimeUtils.setCurrentMillisSystem()
    来恢复默认值

    注意:您的提供商需要一种方法使时钟滴答作响,否则所有新的
    DateTime
    实例将具有相同的值。每次调用
    getMillis()
    时,我通常会将该值提前一毫秒

    注2:这只适用于joda时间。它不会影响新java.util.Date()


    注3:您不能再并行运行这些测试了。它们必须按顺序运行,否则其中一个最有可能在另一个测试运行时恢复默认时区。

    可能的重复不是重复;这是一个后续行动。我不确定这将独立于夏令时工作。例如,现在我得到了“美国/太平洋”的时区。现在,因为我们仍然在DST,我得到了-25200的偏移量。但当我们在11月切换回标准时间时,同样的代码将返回-28800。我弄错了吗?这是一个不错的解决方案,但我认为如果并行运行测试,将原始值设回可能会有风险,因为第一个测试完成后,将所有其他测试的时区(静态字段)设回。@CSpille Correct。如果您想并行运行测试,您必须以某种方式对需要此规则的测试进行分组,并围绕该组执行该规则。
    public class UTCTest extends AbstractTZTest {
        @Rule public TZRule tzRule = new TZRule( DateTimeZone.forID( "..." );
    }