Objective C - Unit testing core functionality in private methods?

I've been in many situations where my core logic is in private methods. How would you go about unit testing that, is there any kind of compile time manipulation to ignore compile errors for unknown/private methods? I know that for the second part of the code I could use performSelector, but is that a reasonable solution?

For instance:

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

EDIT:

Here is an example to demonstrate why I feel like I need to test some private methods. Are these tests not reasonable? How else would I test that calling clear actually does what it suppose to do?

- (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];
}

Answers


Methods are never "private" in the sense that once a class implements a method, it can be sent my anyone.

So, let's say you have a class Foo with a "private" method bar that is not in the interface declaration. You could, from anywhere, still invoke bar though you may get a compiler diagnostic.

Probably the simplest approach is to declare the methods in a category that your tests use. For example:

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

Now, you can use them without the compiler complaining either. Note, the methods do not have to be implemented in an actual MyPrivateMethodsUsedForTesting category. This technique is also sometimes referred to as an "informal protocol."

EDIT

Also, as noted by others, that if you need to access private methods, you probably should revisit your design. After ~30 years doing this, there are definitely times where, especially for tests, you need to access private stuff, but most times it means some type of design review is in order.


Need Your Help

Does Objective-C have an operator, function, or method that can return -1, 0, or 1 when comparing 2 integers or floats?

objective-c

I tried to search on Google or Stackoverflow but can't find such an operator. In C we used to defined a cmp macro but is there something built in?

How to add events to templated control in silverlight?

silverlight silverlight-4.0

Bounty Rewarded for any solid tutorial/learning resources regarding wiring up events with templated controls.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.