模拟SUT本身

| 有时候,我感到自己想嘲笑被测者的愿望,我知道它看起来很奇怪。 这是例子。我使用C#,但是没关系。假设您有一个班级管理着一些馆藏。它有方法
public void Insert(int position, T element)
public void Delete(int position)
这些方法的逻辑不是很简单。除了修改集合外,它们还可以例如引发事件,订阅事件或从事件中取消订阅,获取/释放资源或执行计算。这些方法包含在检查此功能的单元测试中。 现在添加一个方法
public void Replace(int position, T element)
{
    Delete(position);
    Insert(position, element);
}
我不确定,但是对我来说,用这种方法再次测试所有这些东西是不值得的。相反,检查此方法是否真的首先调用两者是有意义的。 如果前两个方法属于另一个类或接口,那么使用现代的模拟框架将很容易。但是这些方法属于SUT。 可以做我想做的吗?如果没有,那为什么呢?这是模拟方法的意外缺陷还是设计使然。如果是第一个,是否有解决方法?如果第二,我应该如何设计和测试所描述的程序?
已邀请:
首先,是的,至少在FakeItEasy中可以做到。 其次,这可能不是一个好主意。我说这可能是因为在某些情况下,这至少不是一个很糟糕的主意。在上面的示例中,我想说这可能是个坏主意,但我不确定这是一个真实的示例。这是一个坏主意,因为replace方法也可能是您的类的扩展方法,这样它就很容易测试。 但是,如果您决定在您的情况下是个好主意,这就是您在FakeItEasy中的操作方式(请确保要声明的方法是虚拟的):
// In your set up
var sut = A.Fake<MySut>();
A.CallTo(sut).CallsBaseMethod();

// In your test of the Replace-method
A.CallTo(() => sut.Delete(thePosition)).MustHaveHappened();
我不确定在其他模拟框架中是否很容易做到这一点,但这可能会为您指明正确的方向。 正如我所说,在大多数情况下,这可能不是一个好主意,但我本人已使用了此技术,它可能会很有用。
我不确定您使用的是什么框架,但是我可以在Rhino.Mocks中做到这一点。我没有实例化我的SUT,而是创建了它的存根(请注意,我不是在创建接口的存根,而是创建对象本身的存根)。存根仍将运行SUT的代码,但也会为我跟踪呼叫。
//Create a stub of my SUT, passing the constructor arguments to GenerateStub()
_sut = MockRepository.GenerateStub<SutClass>(_mockedDependency);
这使我可以断言...
_sut.AssertWasCalled(x => x.DoTheStuff(_argObject1, _argObject2),
                     o => o.Repeat.Once());
很漂亮现在我只需要确保我不滥用它即可;) 编辑: 我应该补充一点,以测试方法
DoTheStuff
是否被调用,看来它可能需要为
overridable
(在C#中为
virtual
)。我以为没有必要,但是前几天写的测试却相反。让我知道我是否错了。

要回复问题请先登录注册