2

我正在尝试解耦现有代码以便能够对其进行单元测试。我已经引入了接口来去除对UI对象的依赖。问题是Spring容器的RegisterComponent<T>调用需要一个TComponentType参数,所以我不能调用RegisterComponent<IMyProgressBar>我必须调用RegisterType<TMyProgressBar>.Implements<IMyProgressBar>这意味着我必须在 DUnit 中使用包含进度条类定义的单元,这违背了将 DIContainer 与 ServiceLocater 一起使用的目的,以便在我需要时请求进度条。

我不想创建模拟类并手动实现接口。有没有办法使用 Delphi.Mocks 自动模拟接口而不指定实现类?

4

1 回答 1

3

您显然没有使用最新版本的 Spring4D,因为该功能已于去年 11 月实施(请参阅https://stackoverflow.com/a/11315141/587106中的更新)

目前没有容器的自动模拟,但我喜欢这个想法,并将研究实现一些使这更容易的东西(可能通过改进容器扩展)。

目前,测试用例方法看起来像这样(使用 DSharp 模拟语法):

procedure TMyTestCase.TestSomething;
var
  progressBarMock: Mock<IProgressBar>;
  sut: TTestComponent;
begin
  container.RegisterType<TTestComponent>;
  container.RegisterType<IProgressBar>.DelegateTo(
    function: IProgressBar
    begin
      Result := progressBarMock;
    end);
  container.Build;

  // mock setup

  sut := container.Resolve<TTestComponent>;

  // perform test
end;

无论如何,我强烈建议在不使用 DI 容器的情况下编写单元测试。

如果您的 SUT 有许多依赖项,则使用容器很有吸引力,这通常是违反某些设计原则的标志。

于 2013-04-18T11:28:20.733 回答