断言一个抽象方法被调用
本文关键字:抽象方法 调用 一个 断言 | 更新日期: 2023-09-27 18:04:50
我正在使用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();
}
那么我如何断言受保护的抽象方法实际上是在DoSomethingCool
方法中调用的??
如果它是来自注入依赖项的对象,我将能够使用Moq
设置模拟并断言该方法被调用,但是由于该方法是在Subject Under Test中的抽象方法,我如何断言该方法被调用?
关于这个有很多可以说的:
-
似乎你可能要么测试太多,要么给其他实现太多的控制。
- (太多的控制)通常,如果你想强迫一个方法从你的
abstract class
中的另一个方法调用,你不使它public virtual
。通过这样做,您已经为未来的实现提供了更改此行为的能力。事实上,如果您删除virtual
,那么您可以得到您想要的测试(见下文)。我确实提供了一种方法来保持virtual
,但再次…不推荐。不建议这样做,因为您的SUT是您的模拟…这感觉不对。 - (测试太多)您应该只关心基本的行为,而不是实现细节,以免您的测试变得太脆弱。我假设不仅仅是对
OnDoingSomethingCool
方法的调用,否则你应该让它成为你的主方法。如果主要行为是这个调用(并且不止这个调用),那么我在下面的NotRecommended
方法中覆盖它。
- (太多的控制)通常,如果你想强迫一个方法从你的
-
不应该直接测试抽象类。你可能应该使用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());
}