【问题标题】:Can't fire event from FakeItEasy mock in unit test在单元测试中无法从 FakeItEasy 模拟中触发事件
【发布时间】:2014-09-05 04:37:28
【问题描述】:

我正在使用测试驱动开发在 Mac OS X 上使用 Xamarin Studio 开发一个简单的应用程序。我使用 NUnit 作为测试工具,使用 FakeItEasy 进行模拟。我开发了一个触发事件的对象,我想测试另一个对象对该事件的响应,但是响应对象似乎从未收到任何在测试中触发的事件。

以下代码说明了问题:

using System;
using NUnit.Framework;
using FakeItEasy;

namespace EventTest
{
    public class EventProvider
    {
        public delegate void EventDelegate(object sender, EventArgs arguments);

        public EventDelegate Event;
    }

    class EventResponder
    {
        public EventResponder(EventProvider provider)
        {
            provider.Event += (sender, arguments) => ++EventCount;
        }

        public uint EventCount { get; private set; }
    }

    [TestFixture]
    public class EventResponderTest
    {
        [Test]
        public void ResponseToFiredEvent()
        {
            var eventProvider = A.Fake<EventProvider>();

            EventResponder responder = new EventResponder(eventProvider);

            eventProvider.Event += Raise.WithEmpty().Now;
            eventProvider.Event += Raise.WithEmpty().Now;
            eventProvider.Event += Raise.WithEmpty().Now;

            Assert.AreEqual(3, responder.EventCount);
        }
    }
}

测试失败,因为 EventCount 为 0。如何使测试通过?

【问题讨论】:

    标签: c# unit-testing events fakeiteasy


    【解决方案1】:

    您的测试不起作用,因为 FakeItEasy 要求 faked 成员是虚拟的,或者更一般地说 - 可覆盖,并且 the same holds for events that FakeItEasy raises。您当前的事件不可覆盖。要解决它,要么:

    • Event 成员更改为虚拟 (public virtual event EventDelegate Event;)
    • EventProvider的实现隐藏在接口后面,伪造接口而不是类,让你的消费者(EventResponder)依赖于接口

    【讨论】:

    • @BlairConrad:如果框架确实在遇到这种情况时发出警告/抛出(尝试模拟由于 DynamicProxy 限制而无法模拟的东西),那就太好了。 IME,我已经回答的与此问题相关的大量问题以某种方式证明这对初学者来说不是显而易见的话题。
    • 在许多情况下(尽可能多地),当我们尝试模拟不可模拟的东西时,FakeItEasy 确实抛出。尝试在非虚拟方法上运行 A.CallTo。有一个很好的错误。我确信有些地方被遗漏了,但是当我们听到这样的事情时,我们会尝试添加显式错误。在这里,我看不出这怎么可能——根本没有假物体。 Raise 没有可使用的假货,EventResponder 在测试中也没有假货。如果您有不同的想法,并且有时间和意愿进行调查,@jimmy_keen,请找到方法;我很高兴有机会改善这里的行为。
    • 我不确定如何使活动成员虚拟化。当我尝试将其更改为: public virtual EventDelegate Event;编译时出现此错误:修饰符 'virtual' 对此项目无效。如果我尝试类似: public EventDelegate virtual Event;我收到此编译器错误:意外的 sybmol ';'在类、结构或接口成员声明中
    • 看来我想通了;我必须包含 event 关键字。即:公共虚拟事件 EventDelegate Event;
    猜你喜欢
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2010-12-26
    • 2019-11-27
    • 1970-01-01
    相关资源
    最近更新 更多