2010-06-01 39 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 

实际上您可以通过这种方式获取调用列表。

相关问题