9

我遇到过很多情况,我的核心逻辑在私有方法中。您将如何进行单元测试,是否有任何类型的编译时操作来忽略未知/私有方法的编译错误?我知道对于代码的第二部分,我可以使用 performSelector,但这是一个合理的解决方案吗?

例如:

[[self.objectMock expect] privateMethod];
or 
[self.object callPrivateMethodsToExpectSomeOtherBehaviour]

编辑:

这是一个示例来说明为什么我觉得我需要测试一些私有方法。这些测试不合理吗?否则我将如何测试调用 clear 是否真正做到了它应该做的事情?

- (void)clear
{
   self.orderNumber = nil;
   [self.items removeAllObjects];
   // Clear the rest of fields
}

- (void)testClearShouldRemoveOrderNumber
{
   Order *order = [[Order alloc] init];
   OCMockObject *orderPartialMock = [OCmockObject partialMockForObject:order];

   [[orderPartialMock.items expect] setOrderNumber:nil];
   [orderPartialMock clear];
   [orderPartialMock verify];
}

- (void)testClearShouldRemoveItems
{
    Order *order = [[Order alloc] init];
    order.items = [[OCMockObject niceMockForClass:[NSMutableArray class]];

    [[orderPartialMock.items expect] removeAllObjects];
    [orderPartialMock performSelector@selector(clear)];
    [orderPartialMock.items verify];
}
4

4 回答 4

13

方法永远不是“私有的”,因为一旦一个类实现了一个方法,它就可以发送给我的任何人。

因此,假设您有一个Foo带有“私有”方法的类,该方法bar不在接口声明中。bar尽管您可能会获得编译器诊断,但您仍然可以从任何地方调用。

可能最简单的方法是在测试使用的类别中声明方法。例如:

@interface Foo (MyPrivateMethodsUsedForTesting)
- (void)bar;
@end

现在,您也可以在编译器不抱怨的情况下使用它们。请注意,这些方法不必在实际MyPrivateMethodsUsedForTesting类别中实现。这种技术有时也被称为“非正式协议”。

编辑

此外,正如其他人所指出的,如果您需要访问私有方法,您可能应该重新审视您的设计。在这样做了大约 30 年之后,肯定有一些时候,特别是对于测试,你需要访问私有的东西,但大多数时候这意味着某种类型的设计审查是有序的。

于 2012-09-10T14:38:53.563 回答
9

你不应该直接测试你的私有方法。相反,您需要通过公共方法来测试它们。这是在programmers.stackexchange.com 上讨论此事的问题的链接。

答案的总体思路是,您(或维护您的代码的任何其他人)应该可以随时通过更改签名、更改实现或完全删除它们来更改您的私有方法。你班以外的任何人都不应该关心 - 毕竟,这是首先将这些方法设为私有的主要驱动力。

如果您以不兼容的方式更改您的私有方法,那么您的公共方法的单元测试必须中断;否则,你没有很好地测试你的公共方法。实际上,这使得私有方法的单元测试变得不必要。

于 2012-09-10T14:37:27.430 回答
5

一般来说,您不需要对私有方法进行单元测试。

公开的方法告诉你你的类做了什么——这是你关心的,你应该测试这些。私有方法关心你的类如何完成它的工作,你的测试不应该关心工作是如何完成的,只要它被正确地完成。

如果有一天你决定改变你的类的工作方式(即通过改变你的私有方法中的代码),而不改变的类实际做了什么,那么你的单元测试应该继续通过。通过尝试测试类的内部结构,您创建了一个脆弱的测试,即使该类仍然正常工作,它也可能会中断。

如果您发现仅使用公共方法很难彻底测试您的类,那么这是一个警告信号,表明您的类可能太大 - 考虑将其分解成更小的部分。

于 2012-09-10T14:36:36.320 回答
0

你不需要对这些进行单元测试——事实上你不应该。
您将通过公共方法间接测试您的私有方法。私有方法是为您的公共方法完成工作的辅助方法。

因为你应该有足够的自由来改变你喜欢的私有方法,所以单元测试也会适得其反。

但请务必测试您的公共方法的所有案例,以便涵盖所有私有方法。

于 2012-09-10T14:44:23.977 回答