Objective c 台风:如何获得一个符合协议的实例用于生产,另一个用于测试?

Objective c 台风:如何获得一个符合协议的实例用于生产,另一个用于测试?,objective-c,typhoon,Objective C,Typhoon,我已经在Typhone中定义了一个应用程序组件 所以我想说:“这个类X需要注入符合Foo协议的东西。这是一个RealFoo,这是一个TestFoo。当我在现实生活中运行X时,我希望它得到一个RealFoo,但当我运行集成测试时,我希望它得到一个TestFoo” 我该怎么做 有几种推荐的方法可以做到这一点: 使用台风修补器 允许加载基本部件,但一个或多个组件用另一个定义或给定对象实例修补。下面是一个使用模拟组件修补组件的示例: MiddleAgesAssembly* assembly = [Mid

我已经在Typhone中定义了一个应用程序组件

所以我想说:“这个类X需要注入符合Foo协议的东西。这是一个RealFoo,这是一个TestFoo。当我在现实生活中运行X时,我希望它得到一个RealFoo,但当我运行集成测试时,我希望它得到一个TestFoo”


我该怎么做

有几种推荐的方法可以做到这一点:

使用台风修补器

允许加载基本部件,但一个或多个组件用另一个定义或给定对象实例修补。下面是一个使用模拟组件修补组件的示例:

MiddleAgesAssembly* assembly = [MiddleAgesAssembly assembly];
TyphoonComponentFactory* factory = [TyphoonBlockComponentFactory factoryWithAssembly:assembly];

TyphoonPatcher* patcher = [[TyphoonPatcher alloc] init];
[patcher patchDefinition:[assembly knight] withObject:^id
{
    Knight* mockKnight = mock([Knight class]);
    [given([mockKnight favoriteDamsels]) willReturn:@[
        @"Mary",
        @"Janezzz"
    ]];

    return mockKnight;
}];

[factory attachPostProcessor:patcher];

Knight* knight = [factory componentForKey:@"knight"];

将环境相关组件组合在一起

另一种方法是将依赖于环境的组件组合在一起。如果使用的是XML样式的程序集,则可以为生产和测试场景加载不同的文件集,包括基本程序集和任何依赖于环境的文件

在基于块的部件中也可以实现相同的功能,如下所示:

TyphoonComponentFactory* factory = [[TyphoonBlockComponentFactory alloc] initWithAssemblies:@[
    [MiddleAgesAssembly assembly],
    [StarWarsAssembly assembly]
]];

Knight* cavalryMan = [(MiddleAgesAssembly*) factory cavalryMan];
Knight* stormTrooper = [(StarWarsAssembly*) factory stormTrooper];
有关更多信息,请参阅中的组件模块化,或查看包含此示例的


使用台风配置

另一种方法是使用TyphoonConfig。此功能的详细信息如下所示


编辑:

以上示例适用于台风2.0。这仍然适用于台风3.0,但更整洁的是组件激活:

MiddleAgesAssembly *assembly = [[MiddleAgesAssembly new] activate]; 
Knight *knight = [assembly knight];
  • 在Typhone 3.0中,如果协作程序集由协议而不是具体类型支持,或者如果希望重写其中一个程序集,则只需声明协作程序集
  • 您可以使用eg
    [assembly.colloaboratingAssembly stormTrooper]

嗨,贾斯珀,我正在查看您的框架。作为一名DI新手,我想如果您能提供一个使用该框架的weatherClient注入的小示例,我会在Github页面()上受益。经过这么长时间的介绍,我期待着一个愉快的时刻。尽管Github wikipages中解释了如何使用该框架。作为一个新手,我发现手动案例和台风案例之间缺乏心理联系。另外关于使用DI框架的优势,是的,我知道我不想在没有编译器的情况下编程。然而,我仍然不一定理解使用框架的好处。我认为在我手动使用它们一段时间后,可能会有新的见解。现在,我可以想到一个我可能想使用某种抽象的原因:使用DI,我基本上暴露了类中隐藏的需要依赖性的东西,我不喜欢它。目前,该框架的目标是那些在其他语言中使用过DI并了解其好处的用户-文档非常薄。但是我们计划写一本书。与此同时,也许可以结帐a)曼宁的“依赖注入”书b)这个StackExchange问题:c)示例应用程序。DI不会公开类中应该隐藏的部分,它促进了主类之间的明确约定collaborators@huggie简而言之,可以将其视为从应用程序的组成部分围绕应用程序的程序集放置一些“轨道”。(请原谅我的双关语)好吧,我所说的隐藏的意思正是这个被注射的物体现在需要,呃,被注射;而没有DI,它真正使用的对象是实现细节的一部分,用户不需要关心。哇,一本书!现在我明白了,这真的不是一个5美分的概念。()