Unit testing private method - objective C - ios

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?

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.

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.

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

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.

Related

Unit testing private variables in Swift

I have a hard time to grasp how to implement unit tests in a class where all my fields are private.
The class is calculating a user's position with BLE and CoreLocation - not that important. I have a protocol, which when a new location is found I'm calling it and all the classes which conform to that protocol will receive a room id and room name. So, what that means is that literally all the fields in my class are private, because yeah, there's no reason any outside class should access them right? But that also means I can literally test nothing in that class, even though there are quite a few functions which I would like to test. I mean, I could just make the variables internal instead of private, but it just seems wrong to do that just to unit test. I've heard about dependency injection, but it just seems like so much effort.
For example I have this function:
private var beacons: [AppBeacon] = []
private var serverBeacons:[Beacon] = []
private func addBeacons(serverBeacons: [Beacon]){
for beacon in serverBeacons {
let beacon = AppBeacon(id: beacon.id, uuid: beacon.uuid, building: beacon.building, name: beacon.name)
beacons.append(beacon)
}
}
there's no way I can test whether the beacons array was actually filled up as I wanted to or not for example. The public features of my class are basically a function called startLocating and the result which is the room id and name and I know in black box testing which unit testing imitates (right?) I should not care about the intermediate steps, but honestly, with this much functionality should I just say, doesn't matter? And assume i did populate the beacons with some rssi values of my choice, the actual location algorithm is executed on a node.js server, so I honestly don't know what to test client side?
It's classic MVC and there's no way I can change it architecture until the deadline that I have, so I don't know what's the best way to go from here? Just don't test the functionalities? Make the fields internal instead of private? We do testing of the algorithm itself server side, so testing whether the the room id is the expected room id, is already tested.
I read on another post the following:
"Unit testing by definition is black box testing, which means you don't care about the internals of the unit you test. You are mainly interested to see what's the unit output based on the inputs you give it in the unit test.
Now, by outputs we can assert on several things:
the result of a method
the state of the object after acting on it,
the interaction with the dependencies the object has
In all cases, we are interested only about the public interface, since that's the one that communicates with the rest of the world.
Private stuff don't need to have unit tests simply because any private item is indirectly used by a public one. The trick is to write enough tests that exercise the public members so that the private ones are fully covered.
Also, one important thing to keep in mind is that unit testing should validate the unit specifications, and not it's implementation. Validating implementation details adds a tight coupling between the unit testing code and the tested code, which has a big disadvantage: if the tested implementation detail changes, then it's likely that the unit test will need to be changed also, and this decreases the benefit having unit test for that piece of code."
And from that I essentially understand it as that I should just not unit test this?
If you have a private var that would help you write unit tests, change it to private(set) var so that it can be read (but not changed).
Revealing the innards may bother you. If it does, it's possible that there's another type waiting to be extracted from the view controller.
First, the definition of 'unit-test' you have quoted is quite unusual: All definitions from the literature that I am aware of consider unit-testing a glass-box/white-box testing method. More precisely, unit-testing as such is actually neither black-box or white-box - it is the method used for designing the test cases that makes the difference. But there is no reason not to apply white-box test design techniques for unit-testing. In fact, some white-box test design techniques make only sense when applied for unit-testing. For example, when you investigate on unit-testing, you will encounter a lot of discussions about different code coverage criteria, like, statement coverage, branch coverage, condition coverage, MC/DC - for all of which it is essential to know the implementation details of the code and consider these implementation details during test case design.
But, even taking that into account, it does not change much for your particular case: The variables in your code are still private :-) However, you are approaching the testing problem in a too restrictive way: You try to test the function addBeacons for itself, in total isolation even from the other functions in that component.
To test addBeacons, your test cases should not only contain a call to addBeacons, but also some other function call, the result of which would show you if the call to addBeacons was successfull. For example, if you also have a function to find a beacon by name or position, you would first call addBeacon and, to check that this has succeeded, call one of these function to see if your added beacon will be found. These two calls would be part of the same test case.

How to test a private function, in Dart?

Say I defined a private function in a dart file hello.dart:
_hello() {
return "world";
}
I want to test it in another file mytest.dart:
library mytest;
import 'dart:unittest/unittest.dart';
main() {
test('test private functions', () {
expect(_hello(), equals("world"));
}
}
But unfortunately, the test code can't be compiled. But I do need to test that private _hello function. Is there any solution?
While I agree that private methods/classes shouldn't be part of your tests, the meta package does provide an #visibleForTesting attribute, and the analyzer will give you a warning if you attempt to use the member outside of its original library or a test. You can use it like this:
import 'package:meta/meta.dart';
#visibleForTesting
String hello() {
return "world";
}
Your tests will now be able to use it without error or warning, but if someone else tries to use it they'll get a warning.
Again, as to the wisdom of doing this is another question - usually if it's something worth testing, it's something that's worth being public (or it'll get tested through your public interfaces and that's what really matters anyway). At the same time, you might just want to have rigorous tests or test driven principles even for your private methods/classes so - Dart lets you this way.
Edit to add: If you're developing a library and your file with #visibleForTesting will be exported, you are essentially adding public API. Someone can consume that with the analyzer turned off (or just ignore the warning), and if you remove it later you may break them.
Several people believe we shouldn't test private directly: it should be tested through the public interface.
An advantage of following this guidance, is that your test won't depend on your implementation. Said differently: if you want to change your private without changing what you expose to the world, then you won't have to touch your tests.
According to this school of though, if your private is important enough to justify a unit test, then it might make sense to extract it in a new class.
Putting all this together, what you could do here, is:
Create a kind of helper class with this hello method as public. You can then easily unit test it
Let your current class use an instance of this helper class
Test the public methods of your current class which relies on _hello: if this private has a bug, it should be catch by those higher level tests
I don't like either of the above answers. dart's private variable test design is very bad. dart's private visibility is based on library, and each .dart file is a library by default, similar language is rust, but rust can write test code directly in the file, there is no private visibility problem, while dart does not allow this.
Again, I don't think #visibleForTesting is a valid solution,
Because #visibleForTesting can only be used to decorate public declarations, it serves as a mere analysis reminder that developers cannot invoke these declarations in other files,
But from a syntax point of view, developers can't use the _ prefix either, so the form, public, private, becomes confusing. and violates dart's own naming rules.
The argument that one should not test private, or that they should be separated into other classes, is like a justification that is completely unacceptable.
First, private exist because they belong to a business logic/model etc. in a contextual relationship, and it does not make logical sense to separate it into another class.
Second, if you must do this, it will greatly increase the complexity of the code, for example, you move to other classes will lose access to the context variables, or you have to pass a separate reference, or have to create an instance of the class, indeed, then you can finally do some mocks, but you also add a layer of abstraction,
It's hard to imagine that if you were to do this for the whole project, you'd probably double your entire code layers.
For now, If you want your dart package to get more than 90% coverage,
you should not define any private.
It sounds harsh, but that's the real story.
[Alternative] No one seems to have mentioned this yet,
Using part / part of to expose the privates, you can define a test-specific .dart file as the public interface to the library(file) to be tested, and use it to expose all the private declarations that need to be tested. you can name them xxx.fortest.dart
But this is more of a psychological solution, since you are still essentially exposing all private variables/methods
But at least, it's better than splitting class,
Also, if one day dart finally solves this problem, we can simply delete these .fortest.dart files.
A suggestion would be to NOT make methods/classes private but to move code, where you want to hide implementation details, to the lib/src folder.
This folder is considered private.
I found this approach on the fuchsia.dev page in this section under "Testing".
If you want to expose those private methods/classes, that are located in the src folder, to the public, you could export them inside your lib/main file.
I tried to import one of my libraries A (projects are libraries) into another library B and couldn't import code that was in the src folder of library A.
According to this StackOverflow answer it could still be possible to access the src folder from A in library B.
From the dart documentation
As you might expect, the library code lives under the lib directory and is public to other packages. You can create any hierarchy under lib, as needed. By convention, implementation code is placed under lib/src. Code under lib/src is considered private; other packages should never need to import src/.... To make APIs under lib/src public, you can export lib/src files from a file that’s directly under lib.

Rails: what are the main reasons for making methods private?

If the end_user cannot access the source code of the app, why we still need to make some methods private?
I'm reading the Pragmatic Agile Web Development with Rails and I couldn't understand why we need to make the following method private (even after reading the explanation):
private
def current_cart Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
cart = Cart.create
session[:cart_id] = cart.id
cart
end
end
It says that it will never allow Rails to make it available as an action, but as a coder, why would I ever do that myself?
As you say there may be no external reason to make it private. However, it also prevents you — or somebody else using your code — from accidentally making use of the method where you're not supposed to.
See it as a sanity check on your own future behaviour if you will.
It aims to encourage good practices and good code.
The idea is that you have two separate parts to your code:
"Above the line" (Public). This is the interface to the rest of the world. This is the API, where calls are made when using instances of the object. Once created, you know that THIS is the area where changes can affect current usages of the code.
"Below the line (Private). This is where detailed logic resides. This code can be changed and refactored freely without any affect to the public interface.
It may help guide your test writing
Private methods may or may not be (unit) tested.
Public methods are more encouraging of both unit and integrated tests as the fact that is is public means that it is serving as the public face for that code and as it is public it might be called from any other point in the future, so having good tests to make sure it continues to work as advertised is essential.
It may help with security as you have greater control who calls private methods (i.e. only public methods in the same class calling them).
It may help reduce name collisions as you have less names in the public space.
End user might not be able to access your code but someone else in your team can definitely access it and they might change it.
The other benefit of encapsulation is that it allows one class ("server") to make a contract with another class ("client") to provide some service with only a very few things being required to be known about the "server" class such as method signature and return type. The benefit is only realized if the contract of what is required and what is returned remains the same. So, in your example, there is no benefit since the contract was broken by Class A.
Instead of class A changing int type to float, class A should create another new variable of type float for other classes to use so that class B is not "broken" or that contract is not broken between them. Class C could refer to new float variable and Class B could still refer to old int variable and everyone is happy. Better yet, methods would used to retrieve values such as: "getUsersAddress" and "getUSersPhoneNumber" depending on what was wanted.
The real benefit of good encapsulation is that Class A can be completely re-written from top to bottom and as long as the contract is honored as to what Class A is expected to do(have methods "getUsersAddress" and "getUSersPhoneNumber"), then everything in Class B and C works the same. Think carefully about what is exposed and how it is exposed. Things that will change often and break other classes need to be considered carefully before exposing. Good encapsulation means hiding things that are expected to change often so to avoid breaking other classes.
It says that it will never allow Rails to make it available as an action,
Hmm, is this in a Rails Conroller class? And is the book you are working through written for Rails 2.x?
In Rails 2.x, by default any public method in a Controller can be triggered by someone accessing the url /name_of_controller/name_of_method .
But there are some methods in your controller that you don't want anyone on the web to trigger, they weren't intended as 'action methods'. So in Rails 2.x, you mark those as protected or private, something not public. "action method" means a method you intend to be directly triggered via a URL.
In Rails 3.x, routing has generally changed such that only certain methods you explicitly route to are available to be triggered via a URL. However, it might still make sense to mark non-action-methods in a Controller as protected or private so:
It's more clear from skimming the source which methods are action methods and which aren't
As a precaution in case someone changes the routing in such a way that would allow a URL to trigger those methods not intended as action methods
Or for general reasons of code organization that other answers mention, that are not specific to Rails controller classes.
There are several reasons as mentioned above. The interesting thing about this encapsulation in ruby is that it can be violated.
See the "send" method and its brother "public_send".
And for a very common metaprogramming technique that uses this method see:
dynamic finders

When should we consider using private or protected?

Just wondering, when should we actually must use private or protected for some methods in the model?
Sometimes I can't not be bothered to group my methods in private nor protected. I just leave it as it is. But I know it must be a bad practice, otherwise these 2 groupings won't be created in programming.
Thanks.
If you plan to call a method externally, record.method(), then "public"
If it will be used only internally, self.method(), then "private"
If you plan to use it internally, but also in descendants, self.method() # in subclass, then "protected"
I'll give my opinion, and maybe I'll get a kicking for it, but I don't bother with protected or private in Ruby. The reality is, Ruby treats you like an adult, if you want to run a private method from outside the class, you can (there are ways). You can run protected methods outside the class. You can even reassign constants... you can do whatever you like, basically.
And that's why I like it, it's your responsibility. My feeling is, that to mark something as protected or private you are doing two things:
Indicating that you don't think a consumer will need it.
Second guessing what someone else needs.
and in addition, you're making it harder to test, as it can be a real pain testing private methods (see What's the best way to unit test protected & private methods in Ruby? for ways around it)
For those last two reasons, I don't bother with them. If you really wanted some kind of barrier between your classes/methods and the consumers (be they code or developers) then there are other, more effective ways (proxies, obfuscation, encryption, password protected methods etc). Otherwise, why not give them access to the same tools you used?
I don't know Ruby as a special case, but I assume the answer would be the same as for other languages too, so here it is:
A private method can only be accessed by members of the same class, whereas a protected is also available for member of classes that extend the base class where the method is declared.

Long method and testing private methods - design problem

I have a quite long method. It copy an ActiveRecord object with all relations, and changes relations in some cases. To make code more readable, I use private methods. I would like to test them. Technicaly, in Ruby it is no problem, but I suspect, I have bad design. Do you have any advices how to deal with such case?
One school of thought is that each and every private method that matters should be tested implicitly by testing a class's public interface. If a private method didn't get called through the public interface, it is redundant. If your private method is that complex to require its own tests, you should consider putting it in a class of its own and test that class.
In short, it shouldn't be necesary to explicitly test your private methods.
as the saying go's: "Don't touch your privates."

Resources