Testing events with NUnit mock objects
I'm using NUnit to test my application, which I've included a simplified version of below. I'm looking for a way to fire an event on a mock class, and check that the class under test has received it.
The application calls LogIn on the session, and, some time later, the session fires the OnLoggedIn event. I've set up a mock session, and checked that the app calls LogIn on it. Now I want to fire the OnLoggedIn event on it, and check that the app handles this event.
How can I do this?
using System;
using System.Collec开发者_StackOverflow社区tions.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using NUnit.Mocks;
namespace NUnitTest
{
public delegate void LoggedInDelegate();
public interface ISession
{
void LogIn(String username, String password);
event LoggedInDelegate OnLoggedIn;
}
public class App
{
private bool loggedIn = false;
private ISession sess;
public bool LoggedIn
{
get
{
return loggedIn;
}
}
public App(ISession sess)
{
this.sess = sess;
sess.OnLoggedIn += HandleOnLoggedIn;
}
public void LogIn(String username, String password)
{
sess.LogIn(username, password);
}
public void HandleOnLoggedIn()
{
loggedIn = true;
}
}
[TestFixture]
public class AppTest
{
private String USERNAME = "Username";
private String PASSWORD = "Password";
private DynamicMock mockSess;
private App app;
[SetUp]
public void TestInit()
{
// Create objects.
mockSess = new DynamicMock(typeof(ISession));
app = new App((ISession) mockSess.MockInstance);
}
[Test]
public void TestLogin()
{
mockSess.Expect("LogIn", USERNAME, PASSWORD);
app.LogIn(USERNAME, PASSWORD);
mockSess.Verify();
mockSess.Call("OnLoggedIn");
Assert.IsTrue(app.LoggedIn);
}
}
}
Try this article: https://web.archive.org/web/20110914180329/http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html. I didn't really get it, but I will sit down and try it out later, because I have the same problem.
I usually make an oldfashioned stub object (no mocking framework), and raise the event via a Method call in the stub. It goes something like this:
[TestFixture]
public sealed class TestStubbingEvents
{
[Test]
public void FooReceivesEventFromBar()
{
BarStub bar = new BarStub();
Foo foo = new Foo(bar);
Assert.That(foo.EventReceived, Is.False);
bar.RaiseBarEvent();
Assert.That(foo.EventReceived, Is.True);
}
}
internal class Foo
{
public bool EventReceived
{
get; set;
}
public Foo(IBar bar)
{
EventReceived = false;
bar.BarEvent += ReceiveBarEvent;
}
private void ReceiveBarEvent(object sender, EventArgs args)
{
EventReceived = true;
}
}
internal class BarStub : IBar
{
public event BarEventHandler BarEvent;
//Stub method that invokes the event
public void RaiseBarEvent()
{
BarEvent.Invoke(this, new EventArgs());
}
}
public delegate void BarEventHandler(object sender, EventArgs args);
public interface IBar
{
event BarEventHandler BarEvent;
}
This is the best I've come up with, so I am interested to see what the article in the link can produce.
Added:
Note, that the EventReceived property on the Foo class is just an example on how the event affects the object.
精彩评论