4

我终于在我正在处理的项目上强加了一些 TDD,并运行到边缘......我知道我想要的代码,但不知道如何测试它:)

我正在寻找的实现是:

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

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

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

注意我不是用这个测试来测试 FooBuilder 本身,只是协作在那里。

4

2 回答 2

1

通常,依赖注入是用来提供一个完整的对象,说“不是要求这个对象,给你,用这个”。但在这种情况下,我们希望能够实例化一个新对象。因此,我们不需要注入对象,而是注入类。“与其创建一个特定的类,不如在这里实例化其中一个。”

依赖注入有两种主要形式:“构造函数注入”(我将坚持使用术语“构造函数”,即使 Objective-C 将其分为分配和初始化)和“属性注入”。

对于构造函数注入,在初始化器中指定类:

- (instancetype)initWithFooBuilderClass:(Class)fooBuilderClass;

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

@property (nonatomic, strong) Class fooBuilderClass;

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

无论哪种方式,您都可以拥有一个默认初始化程序,该初始化程序可以调用-initWithFooBuilderClass:或将属性设置为[FooBuilderClass class]

然后doSomething会这样开始:

- (void)doSomething
{
    id foo = [[self.fooBuilderClass alloc] init];
    ...
于 2013-07-29T06:08:11.487 回答
0

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

我认为这最终比我开始的设计要好一些。FooBuilder现在对类的用户隐藏了需要新实例化的细节。这也很简单。

它确实具有保持我的被测对象和FooBuilder类之间的强耦合的特性。也许这会在路上咬我——但我打赌 YAGNI 不会。

于 2013-07-30T00:19:14.657 回答