How to unit test a non-public method of a class in objective-c? - objective-c

I have defined a function in a category extension of my class.
Although this function is not a public API, it is a important function and i want to be able to unit test this function.
In the unit test, as expected, XCode complaints the function is not declared.
Is there any way I can get around this?

Generally you should only test interfaces, so maybe the method should actually be public. If you still want the method to be private and write a unit test for it, you can redeclare the method in a category:
Just before your test class add:
#interface ClassUnderTest (IReallyWantToTestPrivateMethodsEvenThoughIShouldnt)
- (void)thePrivateMethodToBeTested;
#end

Don't test private methods. Test the public methods that use the private method. And if the private method doesn't work, the test for the public method that uses it should fail. How a method works (and what private method it calls) is a trivial implementation detail that your test should not be concerned about. Test the result, not how it achieves that result.
See this thread for more about why: https://softwareengineering.stackexchange.com/questions/100959/how-do-you-unit-test-private-methods (They talk about Java, but the principle applies to any language).

Make that function public but put the declaration within #ifdef DEBUG so that it is public only when testing. The released code won't have it as public.

Related

Can I change a private methods visibility in order to unit test them

I see in this answer that for Java you can set the visibility of a private method to "true" in a unit test in order to test the method. Is there something like this available for VBA, so that I can unit test private methods using RD-VBA?
If not, and I have a class that works out some logic in three private methods and give it back to a return value, am I doomed to only give a input value and test the return value, without being able to test the three private methods doing the heave lifting in between?
You shouldn't need to write tests for private methods, regardless of the language. You test your public API, what's private is implementation detail that isn't relevant.
If it is relevant and important enough to be tested on its own, then you should extract that private method to another class, and expose it as a public member of that class.
For example once I had a form and I wanted to limit user input in a textbox to numeric characters, and since I'm reusing that logic elsewhere then instead of treating it as an implementation detail of my form, I extracted a AsciiInputValidator class, and its public IsValidNumericValue method could be tested in every possible way as its own SUT.
Don't test private methods: the public ones invoke them anyway.
Unfortunately the Extract Class refactoring feature is not implemented as of this writing, so for now Rubberduck can't do this automatically for you... but it's definitely in-scope and if you're reading this and you're up for a bit of a C# metaprogramming challenge, go for it, pull requests are always welcome!
Can you add a public wrapper like
public sub testPrivateSub(param1,param2...)
PrivateSub(param1,param2....)
end sub
private sub PrivateSub(param1,param2....)
....
end sub

Testing multiple public methods that call the same private method

I'm trying to figure out whether it's an API design flaw, it is actually OK, or the SRP is being violated.
I have 2 public methods initialize() and onListRefresh(). Both of them call the same private method updateList(). The only difference between both of them is that initialize() also check for a null argument to throw an exception.
The issue is that in order to test both public methods, I practically have to copy and paste the same mocks, stub, expectations and assertions, which are all for what happens on the private method, and it feels wrong. So which one is it:
Is there a flaw in the public API design?
It's all right, that's how it's supposed to be.
SRP is being violated by using initialize() to do both checking for an argument AND calling updateList()
I'd go with 2, and stick with the parallel tests. But here's something that may be calling to you from the test code: Extract helper methods.
This can happen anywhere in the Arrange, Act, Assert phases of the tests. You may extract helpers in all 3 phases. The trick is good names, so that the tests express, simply and legibly, what they are there for.

How can I do unit testing for private function in Visual Studio (VB.Net and C#)?

I know it may sound like a silly question as I've heard many saying that you should only do unit testing for public function and indeed, visual basic.net in Visual studio IDE only allows me to do unit testing for public function.
However, I got a public function that is calling to many other private functions.
If I do unit testing for that public function, that would be too complicated. I only want to test each private function individually to make sure it works correctly first, before jumping to the parent public function.
One solution I've had in my mind is that I could change all private functions to public ones so that Visual Studio allows me to do unit testing for them. But it is annoying me as I don't want them to be public.
Is there any suggestions you could let me know please?
many thanks in advance.
N.T.C
If you really can't break the code out into separate classes, you could change all of the private functions to be protected and then create a private class within your test class that inherits from the class you're trying to test (this would be named as a fake or stub, hence my advice to make it private. You don't want code outside of the test class to interact with this). Within your inherited class, create public functions for each of the now protected functions that simply call through to the base and write your unit tests against those instead.
I apologize if this capability is not available in VB:
Create a sub-class of the class you want to test. Ensure that the sub-class has public interfaces to the private functions.
As for "only unit test public functions?" That's horse manure. You test what might fail. For instance, you might have a class with only one public function, and you want to refactor into a set of calls on private functions to decrease the complexity. If you have to refactor your solution for any reason (as one of the comments suggested), then the first step is to have all the pieces of the solution tested that you will have to change during the refactoring.

How to assign value to an implementation of an interface, but the interface doesn't have setter method?

I have an interface: Show, and i have the implementation class calls ShowImpl, and also i have a implementation class calls ManageShowImpl. I have completed all the methods inside ManageShowImpl. Now i am doing Junit testing. The method i defined in the ManageShowImpl, for example: addShows(Show... shows), now i want to assign values to the show array: Show[], but in the interface: Show, i don't have setter method(which is not supposed inside interface), can some expert tell me how can i add the value to Show[].
If I understood correctly your issue, I think you can simply set values in your constructor:
public class ShowImpl implements Show{
private Show[] shows;
public ShowImpl(Show... shows){
this.shows = shows;
}
#Override
public void someInterfaceMethod(){
// ...
}
}
(I am not a junit expert, or even a beginner, but maybe I can inspire a few to answer. I have done a fair amount of testing.)
Given a class with a constructor, you can always create an instance, fill it with whatever data you want, and test it any way you want. Interfaces are a lot more limited. Testing aside, this is a very good thing. It limits the damage someone can do if they get hold of an interface implementation; it safely encapulates the data. But you cannot test an interface in isolation. You need to create an instance of an implementing class first. At that point you should fill in your array. Then pass it to a test method as an interface instance to test the interface.

Testing private methods, clarification needed

In my src, there exist a class which contains a method
public static boolean doExtensionsMatch(String s, String t) {
There is nothing wrong with it, except that there is no need for it to be public. It is used inside the class where it is declared.
It is public however, since some time ago, i felt this method needed to be tested directly and thus, private visibility did not work for me.
At this point:
I'd rather not throw away those tests. If i make the method private however, tests will become unusable.
I would rather for tests to remain in it's current src-test folder, thus maintaining separate locations for source and tests
So, you tell me, what should i do?
Should i change the method to private and delete the tests?
You test interface to prove that class behaves as it should.
So private methods don't need to be tested as long as they aren't accessible. And even more - you shouldn't care of how interface does its work, you should be fine with just the results.
You test the behaviour, not the implementation.
I would suggest using partial classes. If your test classes are partial classes of the class to be tested they will have access to all methods and variables whether or not they are public.