OCMock测试分配了一个对象并对其调用了一个方法



我终于把一些TDD强加给了我正在进行的项目,并陷入了边缘。。。我知道我想要的代码,但不知道如何测试:)

我正在寻找的实现是:

- (void) doSomething
{
    FooBuilder *foo = [[FooBuilder alloc] init];
    [foo doSomethingElseWithCompletionBlock:^{
        [self somethingDone];
    }];
}

因此,我希望我的测试验证a)被测试的方法分配了一个新的FooBuilder,b)该方法然后在新对象上调用一个方法。

我该怎么做?我开始尝试模拟alloc类方法,但很快就确定这条路是疯狂的。

注意,我并没有用这个测试来测试FooBuilder本身,只是协作是存在的。

通常,依赖注入用于提供一个完整的对象,表示"与其要求这个对象,不如使用这个。"但在这种情况下,我们希望能够实例化一个新对象。因此,我们所要做的不是注入对象,而是注入类。"与其创建一个特定的类,不如实例化其中一个。"

依赖注入有两种主要形式:"构造函数注入"(尽管Objective-C将其分为分配和初始化,但我仍然使用"构造函数"一词)和"属性注入"。

对于构造函数注入,请在初始值设定项中指定类:

- (instancetype)initWithFooBuilderClass:(Class)fooBuilderClass;

对于属性注入,请指定属性中的类:

@property (nonatomic, strong) Class fooBuilderClass;

构造函数注入更清晰,因为它使依赖关系变得明显。但你可能更喜欢房地产注入。有时我会从一种方式开始,然后向另一种方式重构,改变我的想法。

无论哪种方式,都可以有一个默认的初始值设定项,它可以调用-initWithFooBuilderClass:,也可以将属性设置为[FooBuilderClass class]

然后doSomething会这样启动:

- (void)doSomething
{
    id foo = [[self.fooBuilderClass alloc] init];
    ...

我最终通过向FooBuilder添加一个新的类方法来解决这个问题,该方法将一个完成块作为参数。因此,我已经有效地将实例化和方法调用从测试中的对象转移到了collaborator对象中。现在我可以模拟那个单类方法调用了。

我认为这最终会比我刚开始的设计稍微好一点;需要实例化新的CCD_ 7的细节现在对该类的用户隐藏。它也很简单。

它确实具有这样的特性,即它保持了我的测试对象和FooBuilder类之间的强耦合。也许这会咬我一口——但我打赌它不会。

最新更新