4

我正在向一些粗糙的遗留代码添加测试,以便有足够的信心认真重构它。问题之一是编写代码的人显然没有尝试使代码可测试(假设他们从未编写过单个单元测试!)

一个常见的问题是目前没有接口,只有 11 级深度的继承链。我正在使用 Rhino Mocks 将被测类与其依赖项隔离开来,但由于我正在模拟一个类,而不是一个接口,所以如果它具有virtual关键字,我只能存根只读属性。

我目前的想法是我只需将virtual关键字添加到属性中。没有计划将任何进一步的对象添加到现有的依赖链中,它将允许编写测试。

是否有反对添加virtual关键字的任何论据,或者这是一个可以接受的妥协以便进行测试?

示例代码...

在测试类中:

var someClassStub = MockRepository.GenerateStub<SomeClass>();
someClassStub.Stub(s => s.SomeProperty).Return("Test");

在某些类中:

public virtual string SomeProperty {
    get {
        return someDependency.SomeMethod();
    }
}
4

2 回答 2

1

反对添加的主要论点virtual是它歪曲了你的意图。派生类的virtual关键字信号您期望此属性可能会被覆盖。

我不会使用virtual,而是像下面这样模拟依赖项:

var mockedDependency = MockRepository.GenerateMock<IDependency>();
mockedDependency.Expect(x => x.SomeMethod())
                .Returns("whatever your test dictates");

var target = new SomeClass(mockedDependency);

mockedDependency.VerifyAllExpectations();

然后将其注入到新创建的重载构造函数中,如下所示:

public SomeClass(IDependency dependency) : base()
{
    this.someDependency = dependency;
}
于 2013-04-05T17:33:52.517 回答
0

与其virtual到处添加,不如使用一些更安全的方法使您的代码最初可测试。就个人而言,我强烈建议使用 Visual Studio 提供的“提取接口”工具,并在可能安全的情况下用接口替换具体的类引用。然后,模拟接口而不是具体类。

如果您使用不支持提取接口的 Visual Studio(或其他 IDE)版本,您所要做的就是跟踪该类的所有公共成员并将它们添加到接口并创建您的具体类实施它。

您的首要任务应该是获得最初的一组测试。这样,您以后可以在合理确定您的代码没有损坏的情况下进行更危险的更改。

对于任何致力于使旧的遗留代码单元测试的人,我强烈建议阅读《有效地使用遗留代码》一书。这个价格很值。以至于我的经理最终给我的办公室买了一份副本来咨询。

于 2013-04-05T17:44:25.387 回答