Objective C – 在私有方法中unit testing核心function?

我在许多情况下,我的核心逻辑是在私人方法。 你将如何去unit testing,是否有任何一种编译时操作忽略未知/私有方法的编译错误? 我知道对于代码的第二部分,我可以使用performSelector,但这是一个合理的解决scheme?

例如:

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

编辑:

下面是一个例子来说明为什么我觉得我需要testing一些私有方法。 这些testing不合理吗? 我怎么会testing那个调用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]; } 

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

所以,假设你有一个Foo类,它有一个不在接口声明中的“private”方法bar 。 你可以从任何地方,仍然调用bar虽然你可能会得到一个编译器诊断。

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

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

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

编辑

另外,正如其他人所指出的,如果你需要访问私有方法,你可能应该重新访问你的devise。 大约30年之后,这样做肯定有时间,特别是对于testing而言,您需要访问私人内容,但大多数时候这意味着某种types的devise审查是有序的。

你不应该直接testing你的私有方法。 相反,你需要通过公共方法来testing它们。 这里是一个关于programmers.stackexchange.com讨论此事的问题的链接。

答案的一般概念是,您(或任何其他人维护您的代码)应该随时通过更改签名,更改实现或完全删除它们来随意更改您的私有方法。 毕竟,class级以外的人都不应该在乎,毕竟这是首先将这些方法隐藏起来的主要原因。

如果以不兼容的方式更改私有方法,那么公共方法的unit testing必须中断; 否则,你没有做好testing你的公共方法的工作。 实际上,这不需要对私有方法进行unit testing。

一般来说,你不应该单独testing私有方法。

公开的方法告诉你你的class级做什么 – 这是你关心的,你应该testing这些。 私人方法关心你的class级如何工作,只要能够正确完成,你的考试不应该关心工作如何完成。

如果有一天你决定改变你的类的工作方式(即通过改变私有方法中的代码),而不改变你的类实际做了什么 ,那么你的unit testing应该继续通过。 通过尝试testing你的类的内部,你创build了一个脆弱的testing,即使这个类仍然正常工作,这个testing可能会失败。

如果你发现使用公开的方法来彻底地testing你的课程是很困难的,那么这是一个警告信号,你的课程可能太大 – 考虑把它分解成更小的部分。

你不需要unit testing这些 – 事实上你不应该这样做。
您将通过公共方法间接testing您的私有方法。 私有方法是辅助方法来完成公共方法的工作。

既然你应该有足够的自由来改变你的私有方法,因为你喜欢unit testing也会产生反效果。

但一定要testing所有的公共方法的情况下,所有的私人方法都包括在内。