如何测试具有大量依赖关系的代码

本文关键字:依赖 关系 代码 何测试 测试 | 更新日期: 2023-09-27 18:06:17

我正在处理一个基本上没有单元测试覆盖的大型代码库。我们即将开始转向一种更加测试驱动的方法,所以我想我应该试着为我添加的一个非常简单的函数写一个单元测试,基本上是

class ClassUnderTest  {
    public void SetNoMatchingImage() {
        currentState.State = FSMState.NoMatchingImage;
        ... // Some more logic
        NotifyViews();
    }
    public ViewStatus GetStatus() {
        ...
        if (currentState.State == FSMState.NoMatchingImage)
           return ViewStatus.EmptyScreen;
        ...
    }
    ...
}

好的,测试一下,我想这样做:

[Test]
public void TestSetNoMatchingImage() {
    ClassUnderTest view = new ClassUnderTest(...);
    view.SetNoMatchingImage();  
    Assert.AreEqual(ViewStatus.EmptyScreen, view.Status); 
}

但是我这里的问题是,ClassUnderTest构造函数接受3个参数的非接口,不能为空,所以我不能容易地创建一个ClassUnderTest。我可以尝试创建这些类的实例或存根,但对它们来说问题是一样的:每个构造函数都接受必须创建的参数。问题是一样的……等等......结果当然是非常大的开销,即使是非常简单的测试也需要大量的代码。

是否有一个好的方法来处理这样的用例,使测试用例更容易编写?

如何测试具有大量依赖关系的代码

当您在没有测试的情况下开始重构一个项目时,如果它的设计没有考虑到依赖注入,并且您使用的模拟框架不能模拟具体类(例如NMock),那么您将遇到很多这样的情况。

正如Andriys刚才提到的,Typemock(和moq)可以模拟具体类,只要它有虚拟成员。

就我个人而言,我会从这三个类中提取一个接口,并作为重构的一部分注入接口,以使类易于测试。我不记得VS是否有一个重构,在2次点击中提取一个界面,这不会花太长时间。

我建议您查看Typemock Isolator框架。根据Roy Osherove的《单元测试艺术》一书,在为遗留代码编写单元测试时,这是最好的选择:

…它是唯一一个允许您在生产代码中创建依赖的存根和模拟而无需重构它的[框架],节省了将组件置于测试中的宝贵时间。

干杯!

我支持对Typemock的推荐,以及其他答案中提出的解决方案。除了已经说过的,Michael Feathers还写了一本关于你正在遇到的模式的书,叫做《有效地使用遗留代码》——

http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ref=sr_1_1?ie=UTF8& qid = 1313835584,老= 8 - 1

这里有一个PDF摘录- http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf