using System; using NUnit.Framework; namespace Developpez.Dotnet.Tests { [TestFixture] public class WeakEventTests { [Test] public void Test_AddHandlerAndRaise() { bool eventRaised = false; // Register a handler for Foo on a new object var bar = new Bar(() => eventRaised = true); Foo += bar.OnFoo; // Raise the event OnFoo(); Assert.IsTrue(eventRaised); } [Test] public void Test_RemoveHandler() { bool eventRaised = false; // Register a handler for Foo on a new object var bar = new Bar(() => eventRaised = true); Foo += bar.OnFoo; // Raise the event OnFoo(); Assert.IsTrue(eventRaised); // Unregister the handler Foo -= bar.OnFoo; // Raise the event again eventRaised = false; OnFoo(); Assert.IsFalse(eventRaised); } [Test] public void Test_DontPreventGarbageCollection() { bool eventRaised = false; // Register a handler for Foo on a new object var bar = new Bar(() => eventRaised = true); Foo += bar.OnFoo; // Raise the event OnFoo(); // We still have a reference to bar, so it hasn't been // collected and the handler should be called. Assert.IsTrue(eventRaised); // Drop the reference to bar and force a GC cycle bar = null; GC.Collect(); // Raise the event again eventRaised = false; OnFoo(); // We don't have a reference to bar anymore, so it should have // been collected, and the handler shouldn't be called. Assert.IsFalse(eventRaised); } #region Dummy event and handler class private WeakEvent _fooEvent = new WeakEvent(); public event EventHandler Foo { add { _fooEvent.AddHandler(value); } remove { _fooEvent.RemoveHandler(value); } } protected virtual void OnFoo() { _fooEvent.Raise(this, EventArgs.Empty); } class Bar { private Action _action; public Bar(Action action) { _action = action; } public void OnFoo(object sender, EventArgs e) { _action(); } } #endregion } }