問題是,如何測試事實,即在調用finalize時對象會分配資源。 爲類代碼:測試終結器和IDisposable
public class TestClass : IDisposable {
public bool HasBeenDisposed {get; private set; }
public void Dispose() {
HasBeenDisposed = true;
}
~TestClass() {
Dispose();
}
}
請注意,我不關心正確執行物/敲定剛纔我想找個首先測試它的方式。在這個階段,假設HasBeenDisposed將被設置爲true,如果Dispose/Finalize潔具被調用。
實際測試中,我寫的樣子:
[Test]
public void IsCleanedUpOnGarbadgeCollection() {
var o = new TestClass();
o.HasBeenDisposed.Should().Be.False();
**var weak = new WeakReference(o, true); // true =Track after finalisation
o = null; // Make eligible for GC**
GC.Collect(0, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
**((TestClass)weak.Target)**.HasBeenDisposed.Should().Be.True();
}
或者我更喜歡(的添加更新後)代碼:
[Test]
public void IsCleanedUpOnGarbadgeCollection() {
WeakReference weak = null;
// Use action to isolate instance and make them eligible for GC
// Use WeakReference to track the object after finalisaiton
Action act =() = {
var o = new TestClass();
o.HasBeenDisposed.Should().Be.False();
weak = new WeakReference(o, true); // True=Track reference AFTER Finalize
};
act();
GC.Collect(0, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// No access to o variable here which forces us to use WeakReference only to avoid error
((TestClass)weak.Target).HasBeenDisposed.Should().Be.True();
}
這個測試
與WeakReference的已更新失敗(PASSES AFTER UPDATE),但我觀察以下(修訂版):
- GC.WaitForPendingFinalizers()不掛起線程和定型例如在Ø,但前提是不能紮根。爲其分配NULL,並在完成後使用WeakReference獲取它。
- Finilize(析構函數)代碼在不包含該實例時在正確的點執行。
那麼測試這個的正確方法是什麼?我錯過了什麼?
我猜想這是一個變量Ø防止GC從收集它。
UPDATE:是的,這是問題。必須改用WeakReference。
這正是我所需要的。你使用一個Action委託將我的代碼放到一個單獨的堆棧框架中,並允許我的單元測試正確地收集這些對象。 – NathanAW 2010-07-02 04:30:30
感謝這個解決方案,它效果很好。對我來說,它只需將原始變量設置爲null即可在沒有委託的情況下工作。 (編輯:對necropost抱歉,沒有注意到日期) – amnesia 2017-02-23 21:20:15