我的方法之一中有以下代码
ZonedDateTime current = Instant.now().atZone(ZoneId.of(AMERICA_NEW_YORK));
我想嘲笑current
在 JUnit 测试中。
我尝试过java.time.Clock
但为此,我需要将其添加到类构造函数中,因为我的代码被写入旧版本的 Spring 中,并且使用基于 XML 的配置,此类会导致问题,因为如果我使用构造函数,它需要 application-context.xml 文件中的构造函数参数和Clock
.
有没有办法避免构造函数配置和模拟current
在上面的代码中。
Update
根据帕维尔·斯米尔诺夫的评论,我在下面尝试过,但是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());
基于 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");
}
}
解决方案解释
解决方案依赖于以下事实:Instant.now()
调用Clock.systemUTC().instant()
-
Clock
是抽象的,所以我们监视非静态方法
-
clock.instant()
被嘲笑返回所需的值
-
Clock.systemUTC()
是静态的所以我们需要mockStatic
- using
@Before
/@After
需要关闭 MockedStatic (或者您可以使用try(MockedStatic<Clock> clockMock = mockStatic(Clock.class)) {...}
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)