The point of private properties on an object, like private methods and private instance variables, is so you know what you can safely refactor without having to worry that you’re going to mess up some external client that uses that object.
Ruby provides “sharp knives” that let you get around privateness if you want to. You can use Object#send
, instance_variable_set
or instance_variable_get
to access private properties without invoking errors.
Sometimes tests access private properties. This comes at a cost. When tests involve private properties, the private areas of the object can’t be refactored without also modifying the test.
This tight coupling of the tests to the implementation will make it riskier and more annoying to perform refactoring, which means you’ll probably do less of it, which means the design of your code will probably be worse as a consequence.
Instead of testing private properties directly, it’s better to test the behavior of an object’s private properties indirectly through the object’s public API. That way your tests will be more loosely coupled with your application code and you can enjoy more of the refactoring benefits that testing is supposed to provide.