Ich musste das erst kürzlich machen, und unten ist das, was ich mir ausgedacht habe. Der Grund, warum ich nicht getan habe, was die anderen Posts gesagt haben, ist, dass ich die Idee eines Variablenhaltungszustandes nicht mag und ihn "manuell" zwischen mehreren Ereignissen zurücksetzen muss.
Unten ist der Code des ClassUnderTest
mit NameChanged
Ereignis, das in MyTests
Tests getestet:
public class ClassUnderTest {
private string name;
public string Name {
get { return this.name; }
set {
if (value != this.name) {
this.name = value;
NameChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
public event EventHandler<PropertyChangedEventArgs> NameChanged = delegate { };
}
[TestFixture]
public class MyTests {
[Test]
public void Test_SameValue() {
var t = new ClassUnderTest();
var e = new EventHandlerCapture<PropertyChangedEventArgs>();
t.NameChanged += e.Handler;
Event.Assert(e, Event.IsNotRaised<PropertyChangedEventArgs>(),() => t.Name = null);
t.Name = "test";
Event.Assert(e, Event.IsNotRaised<PropertyChangedEventArgs>(),() => t.Name = "test");
}
[Test]
public void Test_DifferentValue() {
var t = new ClassUnderTest();
var e = new EventHandlerCapture<PropertyChangedEventArgs>();
t.NameChanged += e.Handler;
Event.Assert(e, Event.IsPropertyChanged(t, "Name"),() => t.Name = "test");
Event.Assert(e, Event.IsPropertyChanged(t, "Name"),() => t.Name = null);
}
}
Die unterstützenden Klassen unten sind. Die Klassen können mit allen EventHandler<TEventArgs>
oder erweitert zu anderen Delegaten verwendet werden. Ereignistests können verschachtelt werden.
/// <summary>Class to capture events</summary>
public class EventHandlerCapture<TEventArgs> where TEventArgs : EventArgs {
public EventHandlerCapture() {
this.Reset();
}
public object Sender { get; private set; }
public TEventArgs EventArgs { get; private set; }
public bool WasRaised { get; private set; }
public void Reset() {
this.Sender = null;
this.EventArgs = null;
this.WasRaised = false;
}
public void Handler(object sender, TEventArgs e) {
this.WasRaised = true;
this.Sender = sender;
this.EventArgs = e;
}
}
/// <summary>Contains things that make tests simple</summary>
public static class Event {
public static void Assert<TEventArgs>(EventHandlerCapture<TEventArgs> capture, Action<EventHandlerCapture<TEventArgs>> test, Action code) where TEventArgs : EventArgs {
capture.Reset();
code();
test(capture);
}
public static Action<EventHandlerCapture<TEventArgs>> IsNotRaised<TEventArgs>() where TEventArgs : EventArgs {
return (EventHandlerCapture<TEventArgs> test) => {
NUnit.Framework.Assert.That(test.WasRaised, Is.False);
};
}
public static Action<EventHandlerCapture<PropertyChangedEventArgs>> IsPropertyChanged(object sender, string name) {
return (EventHandlerCapture<PropertyChangedEventArgs> test) => {
NUnit.Framework.Assert.That(test.WasRaised, Is.True);
NUnit.Framework.Assert.That(test.Sender, Is.SameAs(sender));
NUnit.Framework.Assert.That(test.EventArgs.PropertyName, Is.EqualTo(name));
};
}
}
guten Fang! Ich würde meine Antwort aktualisieren, aber es gibt nicht viel Sinn, denn es ist wirklich eine duplex von Drors Antwort auf jeden Fall – theburningmonk