How do I unit test a finalizer?

前端 未结 4 1513
不思量自难忘°
不思量自难忘° 2021-02-05 07:25

I have the following class which is a decorator for an IDisposable object (I have omitted the stuff it adds) which itself implements IDisposable using

4条回答
  •  情话喂你
    2021-02-05 08:26

    It's not easy to test finalization, but it can be easier to test if an object is a subject to garbage collection.

    This can be done with a weak references.

    In a test, it's important to for the local variables to run out of scope before calling GC.Collect(). The easiest way to make sure is a function scope.

        class Stuff
        {
            ~Stuff()
            {
            }
        }
    
        WeakReference CreateWithWeakReference(Func factory)
        {
            return new WeakReference(factory());
        }
    
        [Test]
        public void TestEverythingOutOfScopeIsReleased()
        {
            var tracked = new List();
    
            var referer = new List();
    
            tracked.Add(CreateWithWeakReference(() => { var stuff = new Stuff(); referer.Add(stuff); return stuff; }));
    
            // Run some code that is expected to release the references
            referer.Clear();
    
            GC.Collect();
    
            Assert.IsFalse(tracked.Any(o => o.IsAlive), "All objects should have been released");
        }
    
        [Test]
        public void TestLocalVariableIsStillInScope()
        {
            var tracked = new List();
    
            var referer = new List();
    
            for (var i = 0; i < 10; i++)
            {
                var stuff = new Stuff();
                tracked.Add(CreateWithWeakReference(() => { referer.Add(stuff); return stuff; }));
            }
    
            // Run some code that is expected to release the references
            referer.Clear();
    
            GC.Collect();
    
            // Following holds because of the stuff variable is still on stack!
            Assert.IsTrue(tracked.Count(o => o.IsAlive) == 1, "Should still have a reference to the last one from the for loop");
        }
    

提交回复
热议问题