ppb*_*ppb 14 java junit java-8
我的方法之一中有以下代码
ZonedDateTime current = Instant.now().atZone(ZoneId.of(AMERICA_NEW_YORK));
Run Code Online (Sandbox Code Playgroud)
我想current在 JUnit 测试中进行模拟。
我尝试过,java.time.Clock但为此,我需要将其添加到类构造函数中,因为我的代码写入旧版本的 Spring 并使用基于 XML 的配置,此类会导致问题,因为它需要 application-context.xml 文件中的构造函数参数,如果我使用构造函数与Clock.
有没有办法避免current上面代码中的构造函数配置和模拟。
更新
根据帕维尔·斯米尔诺夫的评论,我在下面尝试过,但current仍然返回今天的日期,但不是我嘲笑的日期。
ZonedDateTime exactOneDay = ZonedDateTime.parse("Sun Oct 21 12:30:00 EDT 2018", Parser);
doReturn(exactOneDay).when(spyEmployeeHelper).getCurrentTime();
employee = getEmployees().get(0);
assertEquals(Integer.valueOf(1), employee.getNoticePeriod());
Run Code Online (Sandbox Code Playgroud)
eze*_*zer 12
基于 Mockito 的解决方案,其中代码使用普通Instant.now()
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import java.time.Clock;
import java.time.Instant;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
public class MockInstantTest {
private MockedStatic<Clock> clockMock;
@BeforeEach
public void setup() {
mockInstant(1640000000); // set desired return value 2021-12-20T11:33:20Z
}
@AfterEach
public void destroy() {
clockMock.close();
}
private void mockInstant(long expected) {
Clock spyClock = spy(Clock.class);
clockMock = mockStatic(Clock.class);
clockMock.when(Clock::systemUTC).thenReturn(spyClock);
when(spyClock.instant()).thenReturn(Instant.ofEpochSecond(expected));
}
@Test
void testWithMockedIstant() {
// invoking Instant.now() will always return the same value
assertThat(Instant.now().toString()).isEqualTo("2021-12-20T11:33:20Z");
}
}
Run Code Online (Sandbox Code Playgroud)
解决方案解释
Instant.now()解决方案依赖于调用的事实Clock.systemUTC().instant()
Clock是抽象的,所以我们监视非静态方法clock.instant()被嘲笑返回所需的值Clock.systemUTC()是静态的所以我们需要mockStatic@Before/来关闭 MockedStatic (或者您可以使用)@Aftertry(MockedStatic<Clock> clockMock = mockStatic(Clock.class)) {...}您可以声明一个返回的函数ZoneDateTime:
public ZoneDateTime getCurrentTime () {
return Instant.now().atZone(ZoneId.of(AMERICA_NEW_YORK));
}
Run Code Online (Sandbox Code Playgroud)
并将该函数的结果分配给该current字段:
ZonedDateTime current = getCurrentTime();
Run Code Online (Sandbox Code Playgroud)
现在您可以使用Mockito 框架将其替换为所需的值:
doReturn(yourValue).when(yourObject).getCurrentTime();
Run Code Online (Sandbox Code Playgroud)