【问题标题】:FakeItEasy not verifying call for Full Framework SignalR testFakeItEasy 未验证对完整框架 SignalR 测试的调用
【发布时间】:2018-08-18 00:27:33
【问题描述】:

我有一个简单的集线器,我正在尝试使用 FakeItEasy 编写一个测试,并且调用客户端的验证没有通过。我有一个在使用 MOQ 和 XUnit 的单独项目中工作的示例。

public interface IScheduleHubClientContract
{
    void UpdateToCheckedIn(string id);
}

public void UpdateToCheckedIn_Should_Broadcast_Id()
{
    var hub = new ScheduleHub();
    var clients = A.Fake<IHubCallerConnectionContext<dynamic>>();
    var all = A.Fake<IScheduleHubClientContract>();

    var id= "123456789";
    hub.Clients = clients;

    A.CallTo(() => all.UpdateToCheckedIn(A<string>.Ignored)).MustHaveHappened();
    A.CallTo(() => clients.All).Returns(all);

    hub.UpdateToCheckedIn(id);
}

我使用 Fixie 作为单元测试框架,它报告:

FakeItEasy.ExpectationException:

预计会找到一次或多次,但没有调用假对象。

以下示例适用于 XUnit 和 MOQ:

    public interface IScheduleClientContract
    {
        void UpdateToCheckedIn(string id);

    }

    [Fact]
    public void UpdateToCheckedIn_Should_Broadcast_Id()
    {
        var hub = new ScheduleHub();
        var clients = new Mock<IHubCallerConnectionContext<dynamic>>();
        var all = new Mock<IScheduleClientContract>();
        hub.Clients = clients.Object;
        all.Setup(m=>m.UpdateToCheckedIn(It.IsAny<string>())).Verifiable();
        clients.Setup(m => m.All).Returns(all.Object);

        hub.UpdateToCheckedIn("id");

        all.VerifyAll();

    }

我不确定我在转换中遗漏了什么?

【问题讨论】:

    标签: c# asp.net-mvc unit-testing signalr fakeiteasy


    【解决方案1】:

    您正在执行一些奇怪的步骤(在我看来,没有看到您的课程的内部),我相信这就是问题所在。

    我认为你的关键问题是你试图验证all.UpdateToCheckedIn 必须在调用hub.UpdateToCheckedIn 之前发生。 (我不确定hub.UpdateToCheckedIn 会调用all.UpdateToCheckedIn,但这听起来很合理。

    还有另一个问题,您将clients.Setup 配置为返回all.Object,这发生在您断言对all.UpdateToCheckedIn 的调用之后。我不确定这是否有必要,但我想我会提到它。

    通常的排序是

    1. 安排假货(以及您需要的任何其他物品)
    2. 行动,但正在运行被测系统 (hub)
    3. 断言对假货采取了预期的措施(或您认为成功所需的任何其他条件)

    我本来希望看到更像的东西

    // Arrange the fakes
    var all = A.Fake<IScheduleHubClientContract>();
    var clients = A.Fake<IHubCallerConnectionContext<dynamic>>();
    A.CallTo(() => clients.All).Returns(all); // if All has a getter, this could be clients.All = all
    
    // … and arrange the system under test
    var hub = new ScheduleHub();
    hub.Clients = clients;
    
    // Act, by exercising the system under test
    var id = "123456789";
    hub.UpdateToCheckedIn(id);
    
    // Assert - verify that the expected calls were made to the Fakes
    A.CallTo(() => all.UpdateToCheckedIn(A<string>.Ignored)).MustHaveHappened();
    

    【讨论】:

    • 我认为 Moq 中的.Verifiable() 不会立即验证调用,它只是表示应该在调用VerifyAll 时进行验证。 (顺便说一下,我有点喜欢这种方法,也许我们应该在 FakeItEasy 中添加类似的东西;它避免了重复调用规范)
    • @ThomasLevesque,你说对了 Moq 的 .Verifiable 的工作原理。说实话,我不爱它。我理解为什么人们喜欢权宜之计,但我喜欢知道在哪里寻找断言的明确性。如果他们愿意,人们总是可以将规范保存到变量中。另请注意,在起订量示例中,实际上没有重用 - all.Setup 是可验证的,但没有配置行为,如果我没看错的话。但我很高兴在 FakeItEasy 存储库中添加这是否是一个很好的功能!
    • 啊,所以你不会喜欢我刚刚打开的问题 ;)
    • 啊...太简单了,喜欢它!情况正是如此。我只是逐行复制我的 MOQ 代码行......但没有考虑 Verifiable/VerifyAll。这就是我得到的。我知道这很简单。脑死亡时刻,我们都明白了。 :-) MOQ 代码是 MS 对 SignalR 集线器进行单元测试的样本的直接样本,我在巡航控制上的时间比平时更多(星期五,一天结束....哈哈)。
    • @BlairConrad - 顺便说一句,喜欢 FakeItEasy!!!! :-) 更容易阅读/关注 imo...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    相关资源
    最近更新 更多