【问题标题】:Moq Assert an abstract method is calledMoq 断言一个抽象方法被调用
【发布时间】:2013-03-20 17:56:49
【问题描述】:

我正在使用 AutoFixture 为我的 Abstract 类编写单元测试,这代表了我正在尝试做的事情:

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();
}

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

如果它是来自注入依赖项的对象,我将能够使用Moq 设置一个模拟并断言该方法已被调用,但由于该方法是一个抽象方法在我的被测主题内,我如何断言该方法被调用?

【问题讨论】:

标签: c# unit-testing moq autofixture


【解决方案1】:

关于这一点可以说一大堆:

  1. 似乎您可能测试太多,或者对其他实现给予太多控制。

    • (控制过多)通常,如果您想强制从abstract class 中的另一个方法调用某个方法,则不要设置为public virtual。通过这样做,您使未来的实现能够改变这种行为。事实上,如果你去掉virtual,那么你就可以得到你想要的测试(见下文)。我确实提供了一种保留virtual 的方法,但同样……不推荐。不建议这样做,因为您的 SUT 是您的模拟......这感觉不对。
    • (测试太多)你应该只关心基本行为,而不是实现细节,以免你的测试变得太脆弱。我假设不仅仅是对OnDoingSomethingCool 方法的调用,否则你应该把它作为你的主要方法。如果主要行为是这个调用(并且不仅仅是这个调用),那么我会在下面的NotRecommended 方法中介绍它。
  2. 您不应该直接测试抽象类。您可能应该使用 The Art of Unit Testing 中 Roy Osherove 所说的 抽象测试类模式。这使得所有实现都可以测试您的行为。然后,您可以传入一个依赖项。如果您想要该示例,甚至是抽象测试类模式的简化示例,请告诉我

/

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());
}

【讨论】:

    猜你喜欢
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    相关资源
    最近更新 更多