Testing a class which preserves its state in private variables
After researching and discussing with some experts, I come up with the solution that if we want to test a class which preserve it's state then the functionality which is preserving the state should go under a separate class. Which will serve the same purpose as setting the variables as private. So, ZoneUpdateDetector
should have a dependency for example: ZoneUpdateStatePreserver
and it should keep the state which was previously inside ZoneUpdateDetector
What is wrong with making a unit test a friend of the class it is testing?
Ideally, you shouldn't need to unit test private methods at all. All a consumer of your class should care about is the public interface, so that's what you should test. If a private method has a bug, it should be caught by a unit test that invokes some public method on the class which eventually ends up calling the buggy private method. If a bug manages to slip by, this indicates that your test cases don't fully reflect the contract you wish your class to implement. The solution to this problem is almost certainly to test public methods with more scrutiny, not to have your test cases dig into the class's implementation details.
Again, this is the ideal case. In the real world, things may not always be so clear, and having a unit testing class be a friend of the class it tests might be acceptable, or even desirable. Still, it's probably not something you want to do all the time. If it seems to come up often enough, that might a sign that your classes are too large and/or performing too many tasks. If so, further subdividing them by refactoring complex sets of private methods into separate classes should help remove the need for unit tests to know about implementation details.
What is good practice to accessing package private variables?
Having accessors/mutators is usually handy even if it is some more code:
If you later introduce some logic when accessing/setting the variable, you can do it just in one place without the need to affect all the classes using the variable - you can easily add features as additional logging, lazy loading, security, validation, ...
You can later change the underlying representation of the field (eg return subtype in some cases)
- You can later introduce lifecycle management of the returned object - eg. Return pooled/cached/singleton/.. object
- You can later decide to return Proxy/decorated object instead without affecting callers
Generally, it is a good idea as it gives you more flexibility, preserves encapsulation and reduces coupling between objects.
Why are instance variables in Java always private?
Instance variables are made private to force the users of those class to use methods to access them.
In most cases there are plain getters and setters but other methods might be used as well.
Using methods would allow you, for instance, to restrict access to read only, i.e. a field might be read but not written, if there's no setter. That would not be possible if the field was public.
Additionally, you might add some checks or conversions for the field access, which would not be possible with plain access to a public field. If a field was public and you'd later like to force all access through some method that performs additional checks etc. You'd have to change all usages of that field. If you make it private, you'd just have to change the access methods later on.
If phone
was private:
Consider this case:
class Address {
private String phone;
public void setPhone(String phone) {
this.phone = phone;
}
}
//access:
Address a = new Address();
a.setPhone("001-555-12345");
If we started with the class like this and later it would be required to perform checks on the phoneNumber (e.g. some minimum length, digits only etc.) you'd just have to change the setter:
class Address {
private String phone;
public void setPhone(String phone) {
if( !isValid( phone) ) { //the checks are performed in the isValid(...) method
throw new IllegalArgumentException("please set a valid phone number");
}
this.phone = phone;
}
}
//access:
Address a = new Address();
a.setPhone("001-555-12345"); //access is the same
If phone
was public:
Someone could set phone
like this and you could not do anything about it:
Address a = new Address();
a.phone="001-555-12345";
If you now want to force the validation checks to be performed you'd have to make it private and whoever wrote the above lines would have to change the second line to this:
a.setPhone("001-555-12345");
Thus you couldn't just add the checks without breaking other code (it wouldn't compile anymore).
Additionally, if you access all fields/properties of a class through methods you keep access consistent and the user would not have to worry about whether the property is stored (i.e. is a instance field) or calculated (there are just methods and no instance fields).
How to preserve state in a function?
Python does not have C-style static variables. However, you can simulate them with closures.
def make_add_one():
x = 0
def _():
nonlocal x
if x < 3:
x += 1
else:
x = 1
return x
return _
add_one = make_add_one()
for _ in range(5):
print(add_one())
There is a duality between objects (data with functions) and closures (functions with data); compare to the class defined by Carcigenicate (slightly modified):
class AddOne:
def __init__(self):
self.hello = 0
def __call__(self):
if self.hello < 3:
self.hello += 1
else:
self.hello = 1
return self.hello
add_one = AddOne()
for _ in range(5):
print(add_one())
One can see the following correspondences:
- class
AddOne
↔ outer functionmake_add_one
- instance
AddOne()
↔ inner functionmake_add_one()
- instance attribute
AddOne().hello
↔ non-local variablehello
insidemake_add_one
How to unit test private methods in Typescript
Technically, in current versions of TypeScript private methods are only compile-time checked to be private - so you can call them.
class Example {
public publicMethod() {
return 'public';
}
private privateMethod() {
return 'private';
}
}
const example = new Example();
console.log(example.publicMethod()); // 'public'
console.log(example.privateMethod()); // 'private'
I mention this only because you asked how to do it, and that is how you could do it.
Correct Answer
However, that private method must be called by some other method... otherwise it isn't called at all. If you test the behaviour of that other method, you will cover the private method in the context it is used.
If you specifically test private methods, your tests will become tightly coupled to the implementation details (i.e. a good test wouldn't need to be changed if you refactored the implementation).
Disclaimer
If you still test it at the private method level, the compiler might in the future change and make the test fail (i.e. if the compiler made the method "properly" private, or if a future version of ECMAScript added visibility keywords, etc).
Related Topics
Swift Video to Document Directory
Swift - Nsdate - Remove Part of Date
Swiftui Vertically Misaligned Text
How to Build a Recursive Function in Swift to Return a String
Swift 4 JSONdecoder Optional Variable
How to Programmatically Change The Xdr Display Reference Mode (Aka Preset) on Macos
Swift Sha256 Encryption Returns Different Encrypted String Compare to Objective C
Swiftui Navigationview Not See Image
Lldb for Swift: Access Computed Property or Perform Function Call in Type Summary Python Script
How to Set Default Clouse Param in View Method
Compiling for iOS 10.3, But Module 'swiftuicharts' Has a Minimum Deployment Target of iOS 13.0
Optional Protocol Requirements, I Can't Get It to Work
Dynamically Set Properties from Dictionary<String, Any> in Swift
F# Asynchronous Http Request - Parse JSON Response
Generating Random Doable Math Problems Swift
Tvos Button Inside Navigationlink Is Not Working