4

我在 Typhoon 中定义了一个 ApplicationAssembly。

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

我怎样才能做到这一点?

4

1 回答 1

6

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

使用台风修补程序

Typhoon-patcher允许加载一个基本程序集,但使用另一个定义或给定对象实例修补一个或多个组件。下面是一个使用 mock 修补组件的示例:

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];

有关更多信息,请参阅Typhoon 文档的组件模块化,或查看示例应用程序,其中包含一个示例。


使用 TyphoonConfig

另一种方法是使用 TyphoonConfig。此功能的详细信息在此处


编辑:

以上示例适用于 Typhoon 2.0。这在 Typhoon 3.0 中仍然可以正常工作,但更简洁的是程序集激活:

MiddleAgesAssembly *assembly = [[MiddleAgesAssembly new] activate]; 
Knight *knight = [assembly knight];
  • 在 Typhoon 3.0 中,如果协作程序集由协议而不是具体类型支持,或者您希望覆盖其中一个程序集,则只需声明协作程序集。
  • 您可以使用例如从协作程序集中解析组件[assembly.colloaboratingAssembly stormTrooper]
于 2013-11-07T14:35:12.067 回答