LocalDateTime.of returns 空
LocalDateTime.of returns null
我正在尝试对使用 java.time.LocalDateTime
的代码进行单元测试。我能够让模拟工作,但是当我添加时间(分钟或天)时,我最终得到一个 null
值。
@RunWith(PowerMockRunner.class)
@PrepareForTest({ LocalDateTime.class })
public class LocalDateTimeMockTest
{
@Test
public void shouldCorrectlyCalculateTimeout()
{
// arrange
PowerMockito.mockStatic(LocalDateTime.class);
LocalDateTime fixedPointInTime = LocalDateTime.of(2017, 9, 11, 21, 28, 47);
BDDMockito.given(LocalDateTime.now()).willReturn(fixedPointInTime);
// act
LocalDateTime fixedTomorrow = LocalDateTime.now().plusDays(1); //shouldn't this have a NPE?
// assert
Assert.assertTrue(LocalDateTime.now() == fixedPointInTime); //Edit - both are Null
Assert.assertNotNull(fixedTomorrow); //Test fails here
Assert.assertEquals(12, fixedTomorrow.getDayOfMonth());
}
}
我明白(我想我明白)LocalDateTime
是不可变的,我认为我应该得到一个新实例而不是 null
值。
原来是 .of
方法给我一个 null
值。为什么?
所以 PowerMockito.mockStatic 弄乱了下一行代码。只需将 fixedPointInTime 的实例化移动到 mockStatic 之前执行....使其全部工作。
根据 documentation:
Use PowerMock.mockStatic(ClassThatContainsStaticMethod.class)
to mock all methods of this class.
和:
Note that you can mock static methods in a class even though the class is final. The method can also be final. To mock only specific static methods of a class refer to the partial mocking section in the documentation.
To mock a static method in a system class you need to follow this approach.
您告诉它模拟所有静态方法,但没有为 of()
方法提供模拟。
解决方法:要么为of()
方法添加mock,要么改为使用部分mocking,这样of()
方法就不会被mock了。
基本上,阅读并遵循文档的说明。
correctly explains about PowerMock usage (and you also figured out ).
我只想添加一种不同的方法。为了测试当前的 date/time,您可以使用 java.time.Clock
。有了这个class,你就可以创建一个fixed clock (a Clock
that always returns the same current date/time) and use it in your test.
有了这个,就不需要模拟静态方法(我不得不从测试中删除 PowerMock 注释 class)。唯一的区别是时钟必须传递给 now()
方法:
@Test
public void shouldCorrectlyCalculateTimeout() {
// create a clock that always returns the same current date/time
LocalDateTime fixedPointInTime = LocalDateTime.of(2017, 9, 11, 21, 28, 47);
ZoneId zone = ZoneId.systemDefault();
Clock clock = Clock.fixed(fixedPointInTime.atZone(zone).toInstant(), zone);
// use the clock in now() method
LocalDateTime fixedTomorrow = LocalDateTime.now(clock).plusDays(1);
// assert (use equals() instead of == because it doesn't return the same instance)
Assert.assertTrue(LocalDateTime.now(clock).equals(fixedPointInTime));
Assert.assertNotNull(fixedTomorrow);
Assert.assertEquals(12, fixedTomorrow.getDayOfMonth());
}
我必须使用 equals()
方法(而不是 ==
)来比较日期,因为 now(clock)
创建了一个新实例,尽管所有实例都对应于相同的 date/time(这才是最重要的,IMO)。
PS: 在上面的代码中,我使用了 JVM 默认时区 (ZoneId.systemDefault()
)。唯一的问题是它 ,因此最好始终明确说明您使用的是哪一个。
在此特定代码中,时区部分被忽略,因此您可以使用任何时区,这不会有太大区别 - 除非您在夏令时转换发生时获得时区和本地日期的组合,这会产生意想不到的结果。
如果您不想依赖它,可以替换 ZoneId.systemDefault()
并改用 ZoneOffset.UTC
(UTC 没有任何夏令时效果)。在这种情况下,您可以像这样创建时钟:
ZoneOffset utc = ZoneOffset.UTC;
Clock clock = Clock.fixed(fixedPointInTime.toInstant(utc), utc);
在您的 class 中创建一个方法,例如
public class SomeClass{
public static void main(String[] args) {
LocalDateTime now = getCurrentLocalDateTime();
System.out.println(now);
}
private LocalDateTime getCurrentLocalDateTime() {
return LocalDateTime.now();
}
}
并且在 Test
Class 你使用:
@PrepareForTest(SomeClass.class)
@RunWith(PowerMockRunner.class)
在测试用例中:
LocalDateTime tommorow= LocalDateTime.now().plusDays(1);
SomeClass classUnderTest = PowerMockito.spy(new SomeClass());
PowerMockito.when(classUnderTest, "getCurrentLocalDateTime").thenReturn(tommorow);
我正在尝试对使用 java.time.LocalDateTime
的代码进行单元测试。我能够让模拟工作,但是当我添加时间(分钟或天)时,我最终得到一个 null
值。
@RunWith(PowerMockRunner.class)
@PrepareForTest({ LocalDateTime.class })
public class LocalDateTimeMockTest
{
@Test
public void shouldCorrectlyCalculateTimeout()
{
// arrange
PowerMockito.mockStatic(LocalDateTime.class);
LocalDateTime fixedPointInTime = LocalDateTime.of(2017, 9, 11, 21, 28, 47);
BDDMockito.given(LocalDateTime.now()).willReturn(fixedPointInTime);
// act
LocalDateTime fixedTomorrow = LocalDateTime.now().plusDays(1); //shouldn't this have a NPE?
// assert
Assert.assertTrue(LocalDateTime.now() == fixedPointInTime); //Edit - both are Null
Assert.assertNotNull(fixedTomorrow); //Test fails here
Assert.assertEquals(12, fixedTomorrow.getDayOfMonth());
}
}
我明白(我想我明白)LocalDateTime
是不可变的,我认为我应该得到一个新实例而不是 null
值。
原来是 .of
方法给我一个 null
值。为什么?
所以 PowerMockito.mockStatic 弄乱了下一行代码。只需将 fixedPointInTime 的实例化移动到 mockStatic 之前执行....使其全部工作。
根据 documentation:
Use
PowerMock.mockStatic(ClassThatContainsStaticMethod.class)
to mock all methods of this class.
和:
Note that you can mock static methods in a class even though the class is final. The method can also be final. To mock only specific static methods of a class refer to the partial mocking section in the documentation.
To mock a static method in a system class you need to follow this approach.
您告诉它模拟所有静态方法,但没有为 of()
方法提供模拟。
解决方法:要么为of()
方法添加mock,要么改为使用部分mocking,这样of()
方法就不会被mock了。
基本上,阅读并遵循文档的说明。
我只想添加一种不同的方法。为了测试当前的 date/time,您可以使用 java.time.Clock
。有了这个class,你就可以创建一个fixed clock (a Clock
that always returns the same current date/time) and use it in your test.
有了这个,就不需要模拟静态方法(我不得不从测试中删除 PowerMock 注释 class)。唯一的区别是时钟必须传递给 now()
方法:
@Test
public void shouldCorrectlyCalculateTimeout() {
// create a clock that always returns the same current date/time
LocalDateTime fixedPointInTime = LocalDateTime.of(2017, 9, 11, 21, 28, 47);
ZoneId zone = ZoneId.systemDefault();
Clock clock = Clock.fixed(fixedPointInTime.atZone(zone).toInstant(), zone);
// use the clock in now() method
LocalDateTime fixedTomorrow = LocalDateTime.now(clock).plusDays(1);
// assert (use equals() instead of == because it doesn't return the same instance)
Assert.assertTrue(LocalDateTime.now(clock).equals(fixedPointInTime));
Assert.assertNotNull(fixedTomorrow);
Assert.assertEquals(12, fixedTomorrow.getDayOfMonth());
}
我必须使用 equals()
方法(而不是 ==
)来比较日期,因为 now(clock)
创建了一个新实例,尽管所有实例都对应于相同的 date/time(这才是最重要的,IMO)。
PS: 在上面的代码中,我使用了 JVM 默认时区 (ZoneId.systemDefault()
)。唯一的问题是它
在此特定代码中,时区部分被忽略,因此您可以使用任何时区,这不会有太大区别 - 除非您在夏令时转换发生时获得时区和本地日期的组合,这会产生意想不到的结果。
如果您不想依赖它,可以替换 ZoneId.systemDefault()
并改用 ZoneOffset.UTC
(UTC 没有任何夏令时效果)。在这种情况下,您可以像这样创建时钟:
ZoneOffset utc = ZoneOffset.UTC;
Clock clock = Clock.fixed(fixedPointInTime.toInstant(utc), utc);
在您的 class 中创建一个方法,例如
public class SomeClass{
public static void main(String[] args) {
LocalDateTime now = getCurrentLocalDateTime();
System.out.println(now);
}
private LocalDateTime getCurrentLocalDateTime() {
return LocalDateTime.now();
}
}
并且在 Test
Class 你使用:
@PrepareForTest(SomeClass.class)
@RunWith(PowerMockRunner.class)
在测试用例中:
LocalDateTime tommorow= LocalDateTime.now().plusDays(1);
SomeClass classUnderTest = PowerMockito.spy(new SomeClass());
PowerMockito.when(classUnderTest, "getCurrentLocalDateTime").thenReturn(tommorow);