【问题标题】:Automated way to write a wrapper and interface for dependency injection of third party libraries?为第三方库的依赖注入编写包装器和接口的自动化方法?
【发布时间】:2015-07-28 15:47:53
【问题描述】:

我正在使用第三方库类 Foo,它具有我的类用作依赖项的多个公共方法和属性。

我想测试我的类并模拟Foo 对象,但它没有接口。所以我在想,我可以在我自己的类中继承这个类,提取一个接口,瞧!我会有一个可注入的接口。

...但当然也有并发症。 Foo 有一堆公共字段。这些不能进入接口,所以我必须为字段编写属性包装器。很烦人。

有没有自动化的方法来做到这一点?我有 ReSharper,但似乎没有办法自动执行此操作,这意味着我正在编写很多乏味的代码。

【问题讨论】:

  • 你在嘲笑virtual的方法吗?如果是这样,您可以使用 Rhino Mocks 的 PartialMock 之类的东西。您将能够覆盖/存根/模拟这些方法并访问公共字段。
  • 哈,当然不是……这个库根本不是为了可扩展而设计的,而且我认为作者从来没有写过单元测试……叹息……
  • 这个怎么样?创建一个将方法公开为virtual 的包装器,然后使用PartialMock!你用的是什么模拟框架?
  • 起订量。似乎做了我想做的一切。
  • 我没有使用 Moq,但看起来你可以使用 callbase 属性进行部分模拟。 stackoverflow.com/questions/4769928/… 所以你可以创建一个包装器,将方法公开为virtual,然后使用一个部分。

标签: c# unit-testing dependency-injection wrapper


【解决方案1】:

您应该将您的测试类分成两个单独的类。一个类包含您需要测试的(业务)逻辑,第二个类充当外部依赖项的适配器。这个适配器类应该实现一个接口并且逻辑类应该依赖于那个接口。这个接口应该模仿外部依赖的API,但是应该在应用程序的需要中定义接口。通过这样做,您可以实现:

您最终会得到一个与外部库紧密耦合的适配器类。此适配器会将传入呼叫转换为可以发送到外部库的内容。此适配器不能单独测试,如果测试很重要,您可能需要为此进行集成测试(取决于外部库的功能)。重要的是,您不必测试外部库是否工作,但您可能仍想测试适配器类的正确性。

【讨论】:

  • 你认为班级有哪两项职责?
  • @JeremyHolovacs:它包含(业务)逻辑和适配器。这是两种不同的职责。
  • 嗯...所以你说的是适配器,我说的是包装器。这些是你心目中的同义词吗?我认为包装器有一个责任:直接翻译外部类的业务逻辑。我想知道我们在这里谈论的是同一件事还是不同的事情?
  • 是的,适配器是一个包装器,但它具有真正从应用程序域“适应”到适应组件的特定功能,而不是仅仅模仿适应组件的接口,这将简单包装。
【解决方案2】:

我会创建一个包装类,它使用你设计的接口和接口,只公开你需要从 Foo 中得到的东西。

例如:

class MyFooWrapper : IFoo
{
   private Foo _foo;
    // methods exposed by IFoo
 }

您可以进一步让 MyFooWrapper 成为一个抽象类以包含属性和任何其他基本功能,但不要将 Foo 放在那里,而是有一个继承 foo 包装器的类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 2011-06-11
    相关资源
    最近更新 更多