簡體   English   中英

JUnit可以模擬OutOfMemoryErrors嗎?

[英]Can JUnit simulate OutOfMemoryErrors?

我有一種嘗試調用內存中圖像轉換器的方法,如果失敗,則嘗試在磁盤上進行圖像轉換。 (內存中的圖像轉換器將嘗試分配圖像的第二個副本,因此如果原始圖像非常大,我們可能沒有足夠的內存。)

public BufferedImage convert(BufferedImage img, int type) {
  try {
    return memory_converter.convert(type);
  }
  catch (OutOfMemoryError e) {
    // This is ok, we just don't have enough free heap for the conversion.
  }

  // Try converting on disk instead.
  return file_converter.convert(img, type);
}

我想為JUnit編寫單元測試來運行每個代碼路徑,但是運行JUnit並且用足夠少的堆來強制OutOfMemoryError是不方便的。 有沒有辦法在JUnit中模擬OutOfMemoryError

在我看來,我可以創建一個BufferedImage的偽子類,它在第一次調用內存轉換器調用的方法時拋出OutOfMemoryError ,但隨后在后續調用中表現正常。 不過,這似乎是一種黑客行為。

你應該嘲笑你的轉換器,而不是使用真實的轉換器。

一旦你這樣做,你只需讓你的模擬庫在調用convert()方法時拋出一個新的OOME。

例如,使用JMock,您可以這樣做:

allowing(mockConverter).convert(with(any(int.class)));
will(throwException(new OutOfMemoryError()));

注入一個stub或mock memory_converterconvert()方法拋出OutOfMemryError

在我看來,我可以創建BufferedImage的偽子類,它在第一次調用內存轉換器調用的方法時拋出OutOfMemoryError,但隨后在后續調用中表現正常。 不過,這似乎是一種黑客行為。

模擬框架通常非常強大,應該讓您指定此行為。 例如,JMock:

http://www.jmock.org/returning.html

在連續呼叫中返回不同的值

有兩種方法可以在不同的調用上返回不同的值。 第一個是定義多個期望並從每個期望中返回不同的值:

 oneOf (anObject).doSomething(); will(returnValue(10)); oneOf (anObject).doSomething(); will(returnValue(20)); oneOf (anObject).doSomething(); will(returnValue(30)); 

doSomething的第一次調用將返回10,第二次調用20和第三次30。

在我看來,我可以創建BufferedImage的偽子類,它在第一次調用內存轉換器調用的方法時拋出OutOfMemoryError,但隨后在后續調用中表現正常。 不過,這似乎是一種黑客行為。

你正走在正確的道路上。 模擬對象正是這些類型的事物有益的。 你真的不關心OutOfMemory錯誤是否合法,你只是想確保拋出/捕獲它並執行另一個路徑。 嘲笑它,你會很高興。

處理OutOfMemoryError並對其進行測試非常困難。 你無法用模擬測試它。 根據OutOfMemoryError異常發生的位置,效果可能會有很大差異。 問題是OutOfMemoryError無法傳遞給您的調用代碼。

如果你想要一個真正的測試,那么你需要在第二個線程內存中分配並產生一個OutOfMemoryError。 這應該重復多次以查看不同的效果。

如果你只想測試你的catch塊,那么你可以嘲笑它。

因為OutOfMemoryError可能會在應用程序中的任何其他線程上產生致命錯誤,所以應該阻止它。 我認為更好的解決方案是計算空閑內存。 所需的內存大小,並在發生異常之前調用磁盤轉換。

暫無
暫無

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

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