使用FakeItEasy声明事件已被引发

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用FakeItEasy声明事件已被引发相关的知识,希望对你有一定的参考价值。

我可以执行以下操作来验证我的ErrorOccurred类的Consumer事件是否已被提升:

using System;
using FakeItEasy;
using Microsoft.VisualStudio.TestTools.UnitTesting;

public interface IService
{
    event EventHandler SomethingBadHappened;
}

class Consumer
{
    private readonly IService service;

    public Consumer(IService service)
    {
        this.service = service;
        service.SomethingBadHappened += (sender, args) => RaiseErrorOccurred();
    }

    public event EventHandler ErrorOccurred;

    protected virtual void RaiseErrorOccurred()
    {
        var handler = ErrorOccurred;
        if (handler != null) handler(this, EventArgs.Empty);
    }
}

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var service = A.Fake<IService>();
        var consumer = new Consumer(service);

        bool eventWasRaised = false;
        consumer.ErrorOccurred += (sender, args) => { eventWasRaised = true; };

        service.SomethingBadHappened += Raise.WithEmpty();

        Assert.IsTrue(eventWasRaised);
    }
}

我想知道是否有更多的“Mocking Framework-y”方式。像下面这样的东西会很好:

        var service = A.Fake<IService>();
        var consumer = new Consumer(service);

        service.SomethingBadHappened += Raise.WithEmpty();

        consumer.ErrorOccurred.MustHaveHappened(/*yada yada/*);
答案

对于FakeItEasy对方法执行任何断言,该方法必须是可伪造的,并在假对象上定义。在这种情况下,consumer是一个“真正的”对象,因此FakeItEasy无法知道它是否做了任何事情。

还有另一种选择,但它是否更像是“模拟框架”,是否有争议。但它可能会吸引你。

创建一个假(在这种情况下handler)来听ErrorOccurred方法:

[TestMethod]
public void TestMethod2()
{
    var service = A.Fake<IService>();
    var consumer = new Consumer(service);

    var handler = A.Fake<EventHandler>();
    consumer.ErrorOccurred += handler;

    service.SomethingBadHappened += Raise.WithEmpty();

    A.CallTo(()=>handler.Invoke(A<object>._, A<EventArgs>._)).MustHaveHappened();
}

这样你就可以查看handler是否被调用。有一些简单的修改可以确保调用是specific number of times,或certain arguments

当然,如果您不关心调用方法的次数或参数,因为handler上只有一种感兴趣的方法,您可以使用这个更简单的调用,它将匹配对处理程序的任何调用(可能是Invoke):

A.CallTo(handler).MustHaveHappened();

以上是关于使用FakeItEasy声明事件已被引发的主要内容,如果未能解决你的问题,请参考以下文章

使用 FakeItEasy 的私有方法和属性的单元测试用例 [重复]

FakeItEasy DbSet / IQueryable<T> - 实体框架 6

为啥代码片段在 matplotlib 2.0.2 上运行良好,但在 matplotlib 2.1.0 上引发错误

Reactreact概述组件事件

VSCode自定义代码片段——声明函数

VSCode自定义代码片段8——声明函数