Objective c 测试已重构的方法(分解为多个方法)?

Objective c 测试已重构的方法(分解为多个方法)?,objective-c,unit-testing,tdd,ocmock,Objective C,Unit Testing,Tdd,Ocmock,正如我以前听到的和最近在中了解到的,一些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 } 这被一个非常漂亮且简

正如我以前听到的和最近在中了解到的,一些
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];
}
这有什么好处吗?这似乎在很大程度上与实际的源代码和方法执行相耦合,而不是调用方法所造成的影响(据我所知,这实际上就是单元测试的内容)。但是调用方法的效果实际上包含在三个单元测试中,测试子方法


当所有其他调用都已在测试中时,进行此测试是好还是不必要?

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

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


为了一致性而嘲弄在很大程度上是不被鼓励的。它已被证明在大多数情况下是有害的。在你真正需要它的地方,把它当作一种工具。

这是一种非常合理的方法。您需要测试两种类型的东西:1)您不想破坏的东西,2)您想记录的东西。如果这种方法符合这些标准中的一个或两个,那就好了

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


最后,您将维护此代码,并负责在代码出现故障时进行修复,因此现在由您来确定测试工作是否超过了以后的风险。

因此,您的意思是:如果我想确定,初始化方法只会执行此操作,而不会执行其他操作,我应该这样嘲笑它来测试它?你说的“为了一致性”是什么意思?什么时候我不应该嘲笑什么?当你从中一无所获的时候。Mocking最初是作为一种工具引入的,用于帮助测试类,使其与IO和副作用隔离开来。然后,这种想法认为你也应该在后台测试控制流——但实际上,这样做的成本大于好处。不要直接调用
viewDidLoad
,因为在你的实际应用程序中不会发生这种情况。只需调用
[sut view]
[mockSut view]
(不确定哪个基于此框架)。实例化视图对象将按照正确的顺序遍历所有视图创建方法。谢谢。我觉得你对这个问题的回答是最完整的。