简体   繁体   English

如何对从具有大量依赖性的基类派生的类进行单元测试?

[英]How to unit test a class derived from a base class with lots of dependencies?

Im trying to unit test a class in some Java code that I've inherited. 我试图在我继承的一些Java代码中对一个类进行单元测试。

Problem is that it derives from a class that is part of the company's application framwwork. 问题是它来自一个类,它是公司应用程序的一部分。 Upon construction, the base class does all sorts of 'clever' stuff, initialising connections to all kinds of services that are needed at runtime. 在构造时,基类会执行各种“聪明”的东西,初始化与运行时所需的各种服务的连接。

But for unit testing purposes I dont need any of that. 但是对于单元测试目的,我不需要任何这些。 I just need to create an instance of the derived class and then I can excercise it. 我只需要创建一个派生类的实例,然后我就可以锻炼它。 If any test specifically need part of the hierarchy I can mock them out. 如果任何测试特别需要层次结构的一部分,我可以嘲笑它们。

So how do I break this dependency? 那么我该如何打破这种依赖呢?

Inheritance can be so brittle. 继承可以是如此脆弱。

Is inheritance a requirement? 继承是一项要求吗? All that "clever" stuff that the base class is doing (eg, establishing connections) are things that a dependency injection engine would normally be providing. 基类正在做的所有“聪明”的东西(例如,建立连接)都是依赖注入引擎通常会提供的东西。

Your class sounds like it would be better off from both a testing and a runtime standpoint if you find a way to not inherit and get its dependencies satisfied by a DI engine. 如果您找到一种不继承并通过DI引擎满足其依赖关系的方法,那么您的类听起来会更好地从测试和运行时的角度来看。 Possible? 可能?

So you have a base class and an extended class. 所以你有一个基类和一个扩展类。 See if you can refactor the extended class to no longer extend the base class, but use it instead. 看看你是否可以重构扩展类以不再扩展基类,而是使用它。 So where you first called parent::fooBar() , you now call this.baseInstance.fooBar() . 所以你第一次调用parent::fooBar() ,你现在调用this.baseInstance.fooBar() This way, you can inject another baseInstance for test purposes. 这样,您可以注入另一个baseInstance用于测试目的。

If you really need to extend the base class to override something, extract the functionality to a third class and make the extended class a proxy. 如果您确实需要扩展基类以覆盖某些内容,请将该功能提取到第三个类,并使扩展类成为代理。 The extended class does nothing else than call methods on the third class. 扩展类除了调用第三个类的方法之外别无其他。 Eg 例如

protected fooBar() {
    return this.realImplementation.fooBar();
}

This way, you can test the real implementation, without instantiating the base class. 这样,您可以测试实际的实现,而无需实例化基类。

We had a similar issue.Lots of framework level classes and dependencies. 我们遇到了类似的问题。很多框架级别的类和依赖项。 We solved it using DI 我们用DI解决了它

I agree with the others who suggest that dependency injection is the way to go in the long term. 我同意其他人的观点,他们认为依赖注入是长期发展的方法。 As a short term hack, you could try to introduce a "global" flag that disables the clever initialization code for testing. 作为一个短期的黑客,你可以尝试引入一个“全局”标志,禁用用于测试的聪明的初始化代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM