Unit testing private method - objective C
Asked Answered
P

4

44

I use GHUnit. I want to unit test private methods and don't know how to test them. I found a lot of answers on why to or why not to test private methods. But did not find on how to test them.

I would not like to discuss whether I should test privates or not but will focus on how to test it.

Can anybody give me an example of how to test private method?

Periodate answered 21/8, 2013 at 10:18 Comment(5)
The same way that you test a normal method, what exactly is the problem you are facing?Skate
The decision to test private methods is a part of the problem space, not a part of the solution space.Defalcation
@Skate It says No visible @interface for myClass declares the selector 'myMethod'Periodate
@dasblinkenlight It says no known instance method for selector 'myMetohd'.Periodate
Possible duplicate of How do I test a class that has private methods, fields or inner classes?Duluth
S
119

Methods in Objective-C are not really private. The error message you are getting is that the compiler can't verify that the method you are calling exists as it is not declared in the public interface.

The way to get around this is to expose the private methods in a class category, which tells the compiler that the methods exist.

So add something like this to the top of your test case file:

@interface SUTClass (Testing)

- (void)somePrivateMethodInYourClass;

@end

SUTClass is the actual name of the class you are writing tests for.

This will make your private method visible, and you can test it without the compiler warnings.

Skate answered 21/8, 2013 at 10:36 Comment(7)
But doing this will expose these methods.Periodate
If you do it in your test class, you are only exposing the methods for the tests.Skate
But you said I have write this in the class I am testing, not in test class.Periodate
No. I said add the category to the top of the file containing your test cases. Where did I say write it in your main class?Skate
Super! I was having big issues about exposing private properties/methods simply for the sake of unit testing. Now at least there's a less intrusive way to expose them. Thanks!!Kattiekatuscha
Is it also possible to expose iVars like this?Conspicuous
I'd opt to make a new header to contain the private definitions, and only import it in the test class, named SUTClass_Internal.hTrope
C
7

A little late, but I just got onto the TDD train.

Private methods shouldn't be tested. Because you write private methods to support your public methods, thus testing your public methods indirectly tests the private methods which support them.

The principle "private methods shouldn't be tested" is supported by the principle "when you need to test private methods, it probably means that you should move those methods to the separate class", thus making them public.

Charteris answered 2/5, 2014 at 10:45 Comment(1)
So this is not TDD then if you wrote a piece of code without writing the unit test first. However, let's say your public method uses few private methods, when it fails how do you know which one failed?Martimartial
R
4

If a method is private, you never should test it.

Think about this. You should test behaviour and contract of your methods instead internal implementation

Racing answered 18/1, 2014 at 0:43 Comment(4)
So... If we had an internal implementation that required testing, does that indicate a design flaw in which that method should've actually been written as public in another class, which is to be concealed privately in the initial class?Inhospitality
If not, then (superficially speaking) making a whole app in a single class with private methods should not be tested.Inhospitality
perfect Mazyod, I completely agree with your supplementary infoRacing
I actually disagree with Mazyod. To understand why, please read my answer.Charteris
A
4

Agreed with @Lord Zsolt

Also please note next (from Test-Driven iOS Development ISBN-10: 0-321-77418-3, ISBN-13: 978-0-321-77418-7 )

Testing Private Methods

I have often been asked, “Should I test my private methods?” or the related question “How should I test my private methods?” People asking the second question have assumed that the answer to the first is “Yes” and are now looking for a way to expose their classes’ pri- vate interfaces in their test suites.

My answer relies on observation of a subtle fact: You already have tested your private meth- ods. By following the red–green–refactor approach common in test-driven development, you designed your objects’ public APIs to do the work those objects need to do. With that work specified by the tests—and the continued execution of the tests assuring you that you haven’t broken anything—you are free to organize the internal plumbing of your classes as you see fit. Your private methods are already tested because all you’re doing is refactoring behavior that you already have tests for.

You should never end up in a situation where a private method is untested or incompletely tested, because you create them only when you see an opportunity to clean up the implementation of public methods. This ensures that the pri- vate methods exist only to support the class’s public behavior, and that they must be invoked during testing because they are definitely being called from public methods.

Accouchement answered 31/8, 2015 at 6:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.