2010-06-01 40 views
11

在C#中,我可以測試這個...有沒有辦法在VB.NET中知道一個處理程序是否已經註冊了一個事件?

public event EventHandler Trigger; 
protected void OnTrigger(EventArgs e) 
{ 
    if (Trigger != null) 
     Trigger(this, e); 
} 

有沒有辦法在VB.NET做到這一點?測試爲空我的意思是?

更多信息

我忘了提。我有用C#編寫的類,但是我正在使用VB.NET編寫我的單元測試。

我在單元測試中嘗試這個...

If myObject.Trigger IsNot Nothing Then 
    ''#do something 
End If 

這是導致它說......「公共事件觸發一個事件,不能直接調用編譯時錯誤。使用的RaiseEvent聲明提出事件。「

Seth

+0

PS ......我的意思是,我DON「T希望提高該事件。其實我要檢查它爲無效,因爲這是我的單元測試。 賽斯 – 2010-06-01 19:28:25

+0

我沒有回答以下問題。 。但是,我還建議你應該測試的是試圖註冊一個事件處理程序,而不是它實際上已經註冊(因爲這將測試已經被很好地測試的CLR功能)。更具體地說,考慮使用[模擬對象](http://martinfowler.com/articles/mocksArentStubs.html),使用[Rhino.Mocks](http://www.ayende.com/projects/rhino-mocks)等框架更容易。 aspx),[Moq](http://code.google.com/p/moq/)或[TypeMock Isolator](http://site.typemock.com/) – hemp 2010-06-01 21:36:09

回答

7

圍繞如何在C#中做這件事情,有一個有趣的討論1129517

由於包含事件的類是用C#編寫的,委託語義確實適用,並且這些技術應該適用於您。但是,您需要將源代碼轉換爲VB.NET才能進行單元測試。

由於在C#程序集下面的類:

public class Triggerific 
{ 
    public event EventHandler Trigger; 

    private static void OnTriggerTriggered(object sender, EventArgs e) 
    { 
     Console.WriteLine("Triggered!"); 
    } 

    public void AddTrigger() 
    { 
     Trigger += OnTriggerTriggered; 
    } 
} 

下面是一些VB.NET代碼將正確地確定是否處理程序登記觸發事件:

<TestMethod()> _ 
Public Sub TriggerTest() 
    Dim cut As New Triggerific 
    cut.AddTrigger() 

    Assert.IsNotNull(GetEventHandler(cut, "Trigger")) 
End Sub 

Private Shared Function GetEventHandler(ByVal classInstance As Object, ByVal eventName As String) As EventHandler 
    Dim classType As Type = classInstance.[GetType]() 
    Dim eventField As FieldInfo = classType.GetField(eventName, BindingFlags.GetField Or BindingFlags.NonPublic Or BindingFlags.Instance) 

    Dim eventDelegate As EventHandler = DirectCast(eventField.GetValue(classInstance), EventHandler) 

    ' eventDelegate will be null/Nothing if no listeners are attached to the event 
    Return eventDelegate 
End Function 
+0

麻...感謝您的回答,並建議您更適合嘲笑。我在我的日程上學習了犀牛嘲笑。 Seth – 2010-06-01 22:36:41

+0

不是很棒。它不起作用。事件不是VB.NET中的一個字段。這隻適用於C#代碼的VB.NET測試方法,在這種情況下,它毫無意義......但是,如果您爲字段名稱執行eventName +「Event」,它將起作用,因爲VB編譯器會自動爲每個事件創建一個字段。 – 2012-04-11 07:13:54

+1

@Quantary OP聲明:「我有用C#編寫的類,但是我正在使用VB.NET編寫我的單元測試。」這個答案解決了哪個問題(並且顯然不是毫無意義的)。如果問一個關於如何爲VB.NET類做這件事的新問題,並且相應地回答它,而不是聲稱答案是「沒有工作「,因爲它的確如此。 – hemp 2012-04-12 10:01:17

11

是的。在Visual Basic中,null被稱爲「Nothing」。

If Trigger IsNot Nothing Then 

更新

以上回答說明如何檢查在VB .NET東西空。不幸的是,事件由VB.NET編譯器處理。

對於此事件定義:

Public Event Trigger as EventHandler 

你可以使用此代碼來檢查訂閱

If TriggerEvent Is Nothing 

通知VB.Net如何添加一個字段後綴Event代表委託。有一個look here for an explanation

+1

+1,但應爲無效神聖?;)我的意思是加油! – kenny 2010-06-01 19:20:22

+0

感謝您的回答。如果你看看我的問題,你會發現觸發器IsNot沒有在vb.net中導致編譯錯誤我忘記提及,在我的問題和你回答如此之快,以至於我在更新問題之前回答。底線......是你的代碼導致編譯錯誤。 Seth – 2010-06-01 19:32:06

+1

@Seth Spearman:做這個,而不是:如果TriggerEvent不是Nothing Nothing – 2012-04-11 07:10:54

8

首先,你的C#代碼有問題。它應該這樣寫的,以減少在錯誤的時間在一個單獨的線程移除的最後一個處理的競爭條件的可能性(暗示爲什麼它的工作原理:多功能使用鑄代表是不可改變的)

public event EventHandler Trigger; 
protected void OnTrigger(EventArgs e) 
{ 
    var temp = Trigger; 
    if (temp != null) 
     temp(this, e); 
} 

其次在VB.Net中完全不需要這個代碼。 VB處理事件的方式稍有不同,因此您不應該檢查是否有任何處理程序已註冊。它的安全,寧願只是引發事件:

Public Event Trigger As EventHandler 
Friend Sub OnTrigger(ByVal e As EventArgs) 
    RaiseEvent Trigger(Me, e) 
End Sub 
+1

Joel ...謝謝你的回覆。我會更新我的代碼。請參閱我的問題的更新(這是我用於學習的第一個C#項目)。在我的情況下,我正在編寫一個單元測試,並且測試正在檢查以確認爲該事件註冊了一個處理程序。但我從你的答案中認爲在vb.net中沒有辦法做到這一點。 – 2010-06-01 19:24:18

1

你不應該有一個單元測試檢查,看是否有處理程序註冊。你如何知道它是否是正確的處理程序,或者它是否是正確的處理程序但行爲不正確?

您的測試有什麼意義?

+0

John, 感謝您的回答。它很好。我正在研究一個「學習」項目,我正在自學C#和單元測試。我想我正在使用單元測試來定義你的api。所以我有一個方法在我的課下測試調用AddTrigger。它會將一個對象添加到該集合中,同時在該對象中註冊一個觸發器。我真的在努力測試什麼,測試什麼。我意識到沒有必要測試.NET或任何其他外部庫。但是,再次......安裝/拆卸確實只定義了一個註冊的觸發器。 – 2010-06-01 19:41:37

+0

所以...繼續...我有兩種測試方法... AddTrigger_TriggerNotExists_TriggerAdded()... AddTrigger_TriggerNotExists_EventRegistered()... 測試第一個測試方法很簡單...只是驗證項目是否添加到採集。它似乎確保代碼......無論如何......將驗證觸發事件是否已註冊。但也許不是。 Seth – 2010-06-01 19:45:02

4

我相信我在VB.Net中使用的語法是:

Public Event Trigger As EventHandler 


Friend Sub OnTrigger(ByVal e As EventArgs) 
    If TriggerEvent IsNot Nothing Then 
     RaiseEvent Trigger(Me, e) 
    End If 
End Sub 

即使TriggerEvent似乎沒有被聲明,編譯器會理解它。它更接近於模擬C#語法。此外,我已經閱讀了某處,該處理程序的代碼分配檢查運行,但我目前無法指出,所以你可以採取或離開。

無論如何,我認爲這是sytax。如果它不完全正確,請不要拍我。

+0

下面是對此的解釋。 VB編譯器自動爲事件聲明生成一個隱藏成員: http://jelle.druyts.net/2003/05/09/BehindTheScenesOfEventsInVBNET.aspx – Technobabble 2012-09-07 17:34:05

0

在VB .NET中有一個有趣的語言「功能」。成員變量是爲暴露代理的事件創建的:

Public Event MyEvent As EventHandler 
Public Sub Test() 

    Dim test = MyEventEvent 
    Dim invokers = test.GetInvocationList() 

End Sub 

實際上您可以通過這種方式獲取調用列表。

相關問題