我在我的單元測驗中使用 mockito (org.mockito:mockito-core:4.7.0) 來嘲笑 Instants。瞬間按預期模擬(見截圖)。

一旦我計算了 2 個模擬瞬間的持續時間,我就會收到以下錯誤:
無法讀取欄位“秒”,因為“結束”為空
我認為問題在于,整個 Instant 類都被模擬了,所以我另外傳遞了Mockito.CALLS_REAL_METHODS以便真正的實作用于我不模擬的方法:
val mock: MockedStatic[Instant] = mockStatic(classOf[Instant], Mockito.CALLS_REAL_METHODS)
然后我收到以下錯誤:
org.mockito.internal.util.reflection.ReflectionMemberAccessor 類無法訪問帶有修飾符“private static”的類 java.time.Instant(在模塊 java.base 中)的成員
MyClass.scala
class ClassToTest() {
def run(): Duration = {
val now = Instant.now()
val now1 = Instant.now()
Duration.between(now1, now)
}
}
測驗.scala
@Test
def test_duration(): Unit = {
val testee = new ClassToTest()
val timeMocked = Instant.parse("2022-08-31T08:55:48.200Z")
val mock: MockedStatic[Instant] = mockStatic(classOf[Instant])
try {
mock.when(() => Instant.now()).thenReturn(timeMocked)
val result = testee.run()
} finally if (mock != null) mock.close()
}
uj5u.com熱心網友回復:
試圖搞笑:“問題不是問題。問題是你對問題的態度”。
我的意思是,您的問題不是對 的靜態呼叫now(),而是認為您應該模擬它。
從時鐘檔案:
應用程式的最佳實踐是將 a 傳遞給
Clock任何需要當前時刻的方法。依賴注入框架是實作此目的的一種方法:public class MyBean { private Clock clock; // dependency inject ... public void process(LocalDate eventDate) { if (eventDate.isBefore(LocalDate.now(clock)) { ... } } }這種方法允許在測驗期間使用替代時鐘,例如固定時鐘或偏移時鐘。
現在,如果您檢查檔案,Instant.now()您會看到:
使用這種方法將阻止使用替代時間源進行測驗的能力,因為時鐘是有效的硬編碼。
public static Instant now() {
return Clock.systemUTC().instant();
}
幸運的是,Instant提供了替代Instant.now(Clock clock):
使用此方法允許使用備用時鐘進行測驗。可以使用依賴注入來引入備用時鐘。
public static Instant now(Clock clock) {
Objects.requireNonNull(clock, "clock");
return clock.instant();
}
Clock通過在您的設計中注入 a :
class ClassToTest {
val clock: Clock = Clock.systemUTC()
def run(): Duration = {
val now = Instant.now(clock)
val now1 = Instant.now(clock)
Duration.between(now1, now)
}
}
您可以輕松實作您想要的:
"test" should {
"should test duration" in {
val testee = new ClassToTest {
override val clock: Clock = mock[Clock]
}
val timeMocked = Instant.parse("2022-08-31T08:55:48.200Z")
when(testee.clock.instant()).thenReturn(timeMocked)
val result = testee.run()
result shouldBe Duration.ZERO
}
}
當然,如果您仍然想模擬對 的靜態呼叫,那么使用PowerMockitonow是可行的,但我不會走這條路,除非沒有更好的選擇。
編輯:從 Mockito 3.4.0 開始,這對Mockito也是可行的,但他們的模擬具有執行緒本地顯式范圍。在這種情況下,您需要模擬Duration.between而不是Instant.now. null問題是因為Duration.between無法計算 2 個模擬之間的持續時間Instant.now()。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/504782.html
上一篇:sparkscala無關輸入'>'轉換中的ParseException
下一篇:如何在ElasticBeanstalk上運行的Tomcat8.5.75中通過ErrorReportValve使用靜態錯誤頁面
