如何在Spring for Delphi中使用带自动布线的Mock?

如何在Spring for Delphi中使用带自动布线的Mock?,delphi,dependency-injection,mocking,ioc-container,spring4d,Delphi,Dependency Injection,Mocking,Ioc Container,Spring4d,如果我有这些接口: ISequencer = interface; IController = interface; 它们的实现(控制器需要控制器注入的定序器): 我在全局容器中注册实现: GlobalContainer.RegisterType<TSequencer>.Implements<ISequencer>; GlobalContainer.RegisterType<TController>.Implements<IController>

如果我有这些接口:

ISequencer = interface;
IController = interface;
它们的实现(控制器需要控制器注入的定序器):

我在全局容器中注册实现:

GlobalContainer.RegisterType<TSequencer>.Implements<ISequencer>;
GlobalContainer.RegisterType<TController>.Implements<IController>;

GlobalContainer.Build;

对于真正的应用程序代码来说,这没关系。但是在测试项目中,我想模拟
ISequencer
。根据测试,当我向容器请求
ISequencer
的实现时,有时我需要真正的实现(
TSequencer
),有时我需要模拟实现(如
TSequencerMock
)。如何进行切换?

您可以为给定接口注册多个实现。然后你可以直呼他们的名字:

GlobalContainer.RegisterType<TSequencer>.Implements<ISequencer>('real');
GlobalContainer.RegisterType<TController>.Implements<IController>('mock');
GlobalContainer.RegisterType.Implements('real'); GlobalContainer.RegisterType.Implements('mock'); 然后你可以根据需要叫他们的名字:

Controller := ServiceLocator.GetService<IController>('mock');
Controller:=ServiceLocator.GetService('mock');
我在这里写了一篇关于如何做到这一点的文章:


实际上我已经读过你的那篇文章了呵呵。。。但这与自动布线功能兼容吗?我不知道该怎么做,因为当我请求IController的实现时,我没有指定我想要什么样的Sequencer,我只是做:
Controller:=ServiceLocator.GetService。Spring自动注入ISequencer的实现。您可以根据编译器指令传递字符串变量,以确定传递的实现是“test”还是“real”。@NickHodges如果ServiceLocator.GetService代码是生产代码的一部分,这里没有写“real”或“test”的方法。正如我已经多次提到的:使用ServiceLocator是不好的。在这个例子中,我们可以看到原因。因为现在如果你想让它返回真实的东西或者模拟的东西,你需要传递一些信息。如果要测试控制器,可以在测试控制器而不是序列器时传入模拟序列器。如果您需要传入一个真正的sequencer,您可能会在测试控制器时问自己为什么需要它。另外:单元测试根本不需要DI容器。如果你不能“手工”完成依赖注入,那你就错了。
GlobalContainer.RegisterType<TSequencer>.Implements<ISequencer>('real');
GlobalContainer.RegisterType<TController>.Implements<IController>('mock');
Controller := ServiceLocator.GetService<IController>('mock');