4

正如我之前听到和最近在Jon Reid 的非常好的截屏视频中了解到的,一些init方法或在 iOS 应用程序中,viewDidLoad方法往往会变得越来越大。我试图重构这个方法:

- (void)viewDidLoad {
    // 10+ lines of setting default property

    // 20+ lines of setting up the navigation bar

    // 20+ lines of resetting the view hierarchy
}

这被一个非常漂亮且简短的方法所取代,该方法包含对其他具有说话名称的方法的调用:

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setDefaultResourceNames];
    [self setupRightBarButtonItems];
    [self restoreNavigationControllerHierarchy];

    [[NSNotificationCenter defaultCenter] addObserver: (...)];

}

现在这三种方法都在进行单元测试,比以前好多了。现在我的问题是,是否也应该viewDidLoad测试该方法?

为此,我在我的测试类中做了一个部分模拟,并编写了以下测试:

- (void)testViewDidLoadShouldInstantiateControllerCorrectly {
    NewsItemDetailsViewController *sut = [[NewsItemDetailsViewController alloc] init];
    id mockSut = [OCMockObject partialMockForObject:sut];
    [[mockSut expect] setDefaultResourceNames];
    [[mockSut expect] setupRightBarButtonItems];
    [[mockSut expect] restoreNavigationControllerHierarchy];

    [mockSut viewDidLoad];

    [mockSut verify];
}

这有什么好处吗?这似乎在很大程度上与实际的源代码和方法执行有关,而不是与调用方法引起的影响有关(据我所知,这实际上是单元测试的内容)。但是调用方法的效果其实都覆盖在三个单元测试中,测试子方法。

进行此测试是好事,还是在所有其他呼叫都在测试中时没有必要?

4

2 回答 2

1

这取决于您要测试的内容。这里没有通用的解决方案;您需要根据自己的专业判断做出决定。

在这种情况下,测试控制流或为其提供回归安全网是否有益?收益是否大于成本?

为了一致性而进行模拟在很大程度上是不鼓励的。在大多数情况下,它已被证明是有害的。在您真正需要它的地方使用它作为工具。

于 2013-01-20T17:20:44.157 回答
1

这是一个完全合理的方法。你想测试两种类型的东西:1)你不想破坏的东西,2)你想要记录的东西。如果这种方法适合您的其中一个或两个标准,那很好。

我认为像这样的测试的主要缺点是它们会给不言而喻的东西增加大量的编码开销。查看设置代码通常非常易读——您可以浏览它并了解发生了什么,因此测试不会增加太多文档价值。如果视图是您每次使用应用程序时使用的视图,那么当您进行 QA 时,如果任何视图设置被破坏,可能会立即清楚,因此测试不会增加太多防御性编码价值。

In the end, you're the one who will maintain this code and be responsible for fixing it when it breaks, so it's up to you to determine whether the testing effort now outweighs the risks later.

于 2013-01-22T20:20:51.090 回答