代码之家  ›  专栏  ›  技术社区  ›  Ben Aston

为单元测试实现受保护的无参数构造函数

  •  4
  • Ben Aston  · 技术社区  · 14 年前

    如果我有一个带有大的旧(很多params)构造函数的类型,那么仅仅为了创建一个派生的“假”类型来用于单元测试中的存根,实现一个受保护的无参数构造函数是一种有效的方法吗?

    另一种方法是提取一个接口,但在一个你不能完全控制的代码库中,这并不总是可取的。。。

    4 回复  |  直到 14 年前
        1
  •  2
  •   Grant Crofton    14 年前

    这并不理想,但它是有效的。

    引用几个比我更了解这个的人的话 The Art of Unit Testing ,Roy Osherove谈到单元测试就像是代码的用户,因此专门为它们提供访问并不一定是件坏事。

    Working Effectively with Legacy Code

    我认为这取决于它是什么类型的代码——如果它是一个公共API,人们很可能会接受受保护的访问,意味着它被设计为被重写,这可能是一个坏主意,但在一个典型的商业应用程序上,它显然不是被重写的,我不认为这是一个问题。在这种情况下,我当然有时会这样做。

        2
  •  2
  •   TToni    14 年前

    从本质上讲,您必须将受保护的视为公共的,从严格的面向对象的角度来看,答案是否定的。

    不过,如果不太麻烦的话,可以添加一个私有的无参数构造函数并通过反射调用它。

        3
  •  1
  •   Andy    14 年前

    无法创建扩展要测试的类的类吗?这样就可以使用自己的构造函数,而无需创建接口。

    修改代码或API以促进单元测试通常是不可取的(请参阅“是否应该对私有方法进行单元测试”的讨论),因此实际使用一个新类而不是修改现有的类可能是前进的方向。

        4
  •  0
  •   Luke Puplett    14 年前

    有一种观点认为,非密封类型应始终声明受保护的无参数构造函数(在其他类型中有参数)。

    这使得子类可以灵活地以自己的方式实例化类,而不是强制向基本构造函数提供参数。

    模拟框架就是这样一个子类的例子,它希望自由能够以自己的方式实例化类;模拟对象不关心设置属性默认值或依赖项,因为它无论如何都会模拟返回值。

    有一天,您自己的类或库客户可能对设置类有着截然不同的想法,并且您不希望某个类型在几个月内就无法进化,因为您被迫将不再需要的东西推入基本ctor。

    很少有绝对需要强制某些初始化值的情况,但请注意,结构不应具有无参数的构造函数。