2011-05-07 57 views
0

我正在使用NUnit來測試我的應用程序,其中包括以下簡化版本。我正在尋找一種方法來在模擬類上觸發事件,並檢查被測試的類是否已收到它。使用NUnit模擬對象測試事件

應用程序在會話上調用LogIn,並在一段時間後會話觸發OnLoggedIn事件。我已經建立了一個模擬會話,並檢查了應用程序調用了LogIn。現在我想對它啓動OnLoggedIn事件,並檢查應用程序是否處理這個事件。

我該怎麼做?

using System; 
using System.Collections.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); 
     } 
    } 
} 

回答

1

試試這篇文章:https://web.archive.org/web/20110914180329/http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html。我沒有真正明白,但我會稍後坐下來嘗試,因爲我有同樣的問題。

我通常會做一箇舊式存根對象(沒有模擬框架),並通過存根中的Method調用引發事件。它是這樣的:

[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; 
} 

這是我最好的,所以我很想看看鏈接中的文章可以產生什麼。

補充:
注意,上Foo類的EventReceived屬性只是對事件如何影響物體的例子。

+0

這是一個很好的解決方案,所以我接受了它,即使它不嚴格匹配問題。 你的鏈接使用NMock2框架,而不是NUnit-mocks。最後,我使用了Moq框架,這更容易處理。 – 2011-05-14 08:49:59