unit-testing - 这种依赖注入(inject)的设计容易理解吗?

标签 unit-testing dependency-injection factory

我正在从事一个拥有大量现有代码库的项目,我的任务是对其中的一小部分进行一些重新设计。现有的代码库没有很多单元测试,但我希望至少我正在处理的部分拥有一整套具有良好代码覆盖率的单元测试。

因为现有的代码库在设计时并未考虑单元测试,所以我需要进行一些结构更改以支持依赖项的隔离。我正在努力使对现有代码的影响尽可能小,但我确实有一些余地可以对其他模块进行更改。我想要关于我所做的更改是否有意义或者是否有更好的方法来解决问题的反馈。我做了以下更改:

  1. 我为我的“协调器”类所依赖的所有重要类提取了接口(interface)。其他开发人员勉强允许这样做,但有一些小提示。

  2. 我修改了协调器类,使其仅引用其操作的接口(interface)。

  3. 我无法使用 DI 框架,但我不得不注入(inject)大量依赖项(包括作为类操作的一部分的额外依赖实例化),所以我将协调器类修改为如下所示(域-具体名称简化):

.

public sealed class Coordinator
{
    private IFactory _factory;

    public Coordinator(int param)
        : this(param, new StandardFactory())
    {            
    }

    public Coordinator(int param, IFactory factory)
    {
        _factory = factory;
        //Factory used here and elsewhere...
    }

    public interface IFactory
    {
        IClassA BuildClassA();

        IClassB BuildClassB(string param);

        IClassC BuildClassC();
    }

    private sealed class StandardFactory : IFactory
    {
        public IClassA BuildClassA()
        {
            return new ClassA();   
        }

        public IClassB BuildClassB(string param)
        {
            return new ClassB(param);
        }

        public IClassC BuildClassC()
        {
            return new ClassC();
        }
    }
}

这允许注入(inject) stub 工厂以返回用于单元测试的模拟依赖项。我担心的是,这也意味着此类的任何用户都可以提供自己的工厂来改变类的操作方式,这并不是真正的意图。此构造函数纯粹用于单元测试,但它具有暗示额外可扩展性的副作用。我通常不会在我使用的其他类中看到这种模式,这让我想知道我是否过于复杂,是否有更好的方法来实现所需的隔离。


注意:代码格式有些奇怪,所以对于上面的格式不佳,我深表歉意。不知道为什么它不允许我正确格式化它。

最佳答案

提议的设计是构造函数注入(inject) 的变体,有时也称为Bastard 注入(inject)。在未开发的环境中,我会认为 Bastard Injection 是一种反模式,但在像您描述的那样的已开发环境中,这是一个很好的折衷方案。

您真的不必担心 Coordinator 类隐含的可扩展性。正确完成,testability is extensibility ,因此理想情况下,注入(inject)的 IFactory 应该代表一个支持可变性的适当领域概念。我知道当您从遗留代码重构时,这可能很难/不可能一蹴而就,但这是您的代码库应该移动的方向。

无论如何,如果您的同事已经厌恶接口(interface)的提取,他们可能不太可能将 IFactory 构造函数参数解释为扩展点。

祝你好运。

关于unit-testing - 这种依赖注入(inject)的设计容易理解吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3397657/

相关文章:

python - 重写依赖提供者是否被认为是不好的做法?

java - Guava:图表的复制构造函数

java - 如何在 TestNG 中生成不同名称的测试?

Python mock.patch autospec 具有属性的类

python - 使用 Flask 和 Python 3 测试文件上传

c# - MSTest 命令行设置

configuration - 统一 : Specify Dependency name during configuration

java - 如何处理依赖注入(inject)策略

Java MVC、工厂和观察者模式结合在一起

c# - Visual Studio 不会运行测试类中的所有单元测试