c# - Moq 断言一个抽象方法被调用

标签 c# unit-testing moq autofixture

我正在使用 AutoFixture 为我的抽象类编写单元测试,这是我正在尝试做的事情的表示:

public abstract class Base
{
    public virtual void DoSomethingCool()
    {
        OnDoingSomethingCool();
    }

    protected abstract void OnDoingSomethingCool();
}

我的单元测试看起来像这样:

[TestMethod]
public void TestMethod1()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());

    var sut = fixture.Create<Base>();

    // How to assert that the OnDoingSomethingCool method was called
    sut.Invoking(x => x.DoSomethingCool())
        .ShouldNotThrow();
}

那么我如何断言 protected 抽象方法实际上是在 DoSomethingCool 方法中调用的呢??

如果它是来自注入(inject)依赖项的对象,我将能够使用 Moq 设置模拟并断言该方法已被调用,但由于该方法是 内部的抽象方法我的 Subject Under Test,如何断言该方法已被调用?

最佳答案

关于这个有很多可以说的:

  1. 看起来您可能测试了太多,或者对其他实现给予了太多控制。

    • (太多的控制)通常,如果你想强制从你的抽象类中的另一个方法调用一个方法,你不会让它成为public virtual。通过这样做,您已经为 future 的实现提供了更改此行为的能力。事实上,如果您删除 virtual,那么您可以获得您想要的测试(见下文)。我确实提供了一种保持 virtual 的方法,但再次...不推荐。不推荐这样做,因为您的 SUT 是您的模拟……感觉不对。
    • (测试太多)你应该只关心基本行为,而不是实现细节,以免你的测试变得太脆弱。我假设不仅仅是对 OnDoingSomethingCool 方法的调用,否则您应该将其作为您的主要方法。如果主要行为是此调用(并且不仅仅是此调用),那么我会在下面的 NotRecommended 方法中介绍它。
  2. 您不应该直接测试抽象类。您可能应该使用 Roy Osherove 在 The Art of Unit Testing 中称为 抽象测试类模式 的东西。 .这使得所有实现都可以测试您的行为。然后你可以传入一个依赖项。如果您想要那个示例,甚至是抽象测试类模式的简化示例,请告诉我

/

using Moq.Protected;

...

public void NotRecommended_ProbablyTestingTooMuch_BrittleTestBelow
{
    //If you MUST keep DoSomethingCool virtual
    //var baseMock = new Mock<Base>{CallBase = true};
    var baseMock = new Mock<Base>();
    baseMock.Protected().Setup("OnDoingSomethingCool");

    baseMock.Object.DoSomethingCool();

    baseMock.Protected().Verify("OnDoingSomethingCool", Times.AtLeastOnce());
}

关于c# - Moq 断言一个抽象方法被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15531227/

相关文章:

c# - 使用 C# 的公钥验证 JWT

c# - 如何剪掉重叠区域?

angular - 如何在 Angular 和 Jasmine 中对取消订阅进行单元测试?

java - 如何对返回 void 的方法进行单元测试 "test the contract"?

c# - 使用 Mocks 验证依赖调用时的 TDD Arrange Act Assert 模式

c# - WebBrowser 控件中的 InvokeMember ("click")

c# - 如果项目存在,如何查询 Cosmos DB 并获取 bool 值

java - 单元测试中的初始化

unit-testing - 使用 'traditional'记录/重播与Moq模型进行模拟

c# - 模拟 UdpClient 进行单元测试