预计不会提高的事件正在提高

时间:2012-10-01 07:57:18

标签: asp.net unit-testing events event-handling nunit

我有事件提升方法,如下所示:

public class Events {

    public event EventHandler<CustomEventArgs> Succeed;

    public virtual void OnSucceed(object sender, params object[] data)
    {
        CustomEventArgs args = new CustomEventArgs(data);

        EventHandler<CustomEventArgs> _succeed = Succeed;

        if (_succeed != null)
        {
            _succeed(sender, args);
        }

    }}

我为 OnSucceed 方法创建了单元测试(使用FluentAssertions):

    [Test]
    public void SucceedShouldNotBeRaisedTest()
    {
        Events events = new Events();

        events.MonitorEvents();

        events.OnSucceed(this,"somedata");

        events.ShouldNotRaise("Succeed");
    }

由于没有该活动的订阅者,我希望它不会提出成功事件

但测试失败,因为成功事件被提升。这有什么问题?!

1 个答案:

答案 0 :(得分:1)

当您致电events.MonitorEvents();时, FluentAssertions 会自动订阅公开事件,以检测事件何时被引发。

您的测试失败,因为您的情况将始终评估为trueif (_succeed != null)。测试时,事件将始终与null

不同

现在我想建议您遵循Jon Skeet提出的方法:

public event EventHandler<CustomEventArgs> Succeed = delegate { } ;

通过上述事件声明,您的活动永远不会是null(无法从班级外部分配活动)

注意:您可以将事件背后的委托指定为其类 中的null,如下所示:

this.Succeed = null;

以上语句将事件后面的委托指定为null,而不是事件本身。通常你不需要做这样的事情,但是如果你这样做,你将不得不重新初始化这样的事件:

this.Succeed = null;
this.Succeed = delegate { };

如果您遵循这些建议,您的活动将永远不会为空,您无需再调用if(this.MyEvent != null)条件来提升您的活动。 (请注意,这种情况完全是技术性的,与域本身无关。)

现在您已删除了技术条件,您可以实际关注域规则,以决定何时举起活动。

最后一步是删除:if (_succeed != null)并添加一个条件,指明是否应该根据您当前的域引发该事件

if(shouldRaiseEvent)
{
    EventHandler<CustomEventArgs> _succeed = Succeed;

    _succeed(...);
}

对于您的测试,您只需要使用所需条件配置您的受试者,以便提高或不提高您的活动。

完整样本:

public class Events {

public event EventHandler<CustomEventArgs> Succeed = delegate { };

public virtual void OnSucceed(object sender, params object[] data)
{
    if (/*[optional] here your domain condition that will indicate if the event should be raised*/)
    {
        // this is a best practice to deal with multi-threading situations
        var _succeed = this.Succeed;
        var args = new CustomEventArgs(data);

        _succeed(sender, args);
    }

}
}