簡體   English   中英

JUnit測試用例中的Thread.sleep

[英]Thread.sleep in JUnit test case

我正在編寫測試用例來測試對象行為。

當對象被實例化時,它必須允許調用方法,只有在500毫秒內調用它時才調用call(),否則它必須拋出異常。

我設計了這樣的Junit測試用例:

@Test(expected = IllegalStateException.class)
public void testCallAfterTimeout() {
    MyObject o= new MyObject();
    //To ensure the timeout is occurred
    Thread.sleep(1000);
    o.call();
}

你認為這是一種好習慣還是我應該采用另一種方法?

非常感謝

在測試用例中使用(實際)時間有兩個問題:

  1. 它從來都不是確定性的。 特別是當您正在尋找高精度時,測試用例將在95%的時間內成功。 但有時它們會失敗,這些是最難調試的類型。 請注意,在多線程測試用例中使用Thread.sleep()時,這更加困難。
  2. 有睡眠的測試用例需要很長時間才能運行,過了一段時間這將使運行完整的測試集變得麻煩。

如果必須,你的方式是可以接受的。 但還有其他選擇:

不要使用真正的時鍾。 而是使用可以從測試用例控制的假(模擬/存根)時鍾:

@Test(expected = IllegalStateException.class)
public void testCallAfterTimeout() {
    MyObject o= new MyObject();
    // Example function that you could make
    advanceClock(1000, TimeUnit.MILLISECONDS)
    o.call();
}

在你的對象中你必須注入一個時鍾。 MyObject看起來像這樣:

class MyObject
{

     public MyObject()
     {
           this(new Clock());
     }

     // Protected so only the test case can access it
     protected MyObject(Clock clock)
     {
           // Save clock as local variable, store creation time etc.
     }
} 

在Java 8中提供了一種機制,例如參見LocalDate.now() 但你也可以輕松實現自己的安靜。

無論它有什么意義,你要求麻煩....

如果你決定在60分鍾后需要超時,你會等待你的測試一小時嗎? 超時應該是MyObject的參數,因此您可以將其設置為一些較小的值進行測試(甚至0以在測試時強制alwyas超時)。

其次,如果你想真正擁有可測試的與時間相關的函數,那么時間和超時應該與你的主邏輯(MyObject類)分開處理。 例如,你可以使用mehtod canCallMethod()的Timekeeper類,它由你的MyObject類調用(並且在它的構造時設置)。 以這種方式在測試中,使用自己的Timekeeper實現初始化MyObject類,該實現返回true或false,並驗證MyObject類的行為是否符合預期。 MyObject可以使用默認構造函數,它始終使用“真實”時間戳,因此外部世界不會強制處理Timekeeper內部。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM