Sealed classes - would you want them in D?

rumbu rumbu at rumbu.ro
Sat May 12 06:42:24 UTC 2018


On Friday, 11 May 2018 at 20:22:52 UTC, H. S. Teoh wrote:
> On Fri, May 11, 2018 at 02:04:34PM -0600, Jonathan M Davis via 
> Digitalmars-d wrote:
>> On Friday, May 11, 2018 19:45:10 rumbu via Digitalmars-d wrote:
> [...]
>> > The first example is unit testing. Having access to the 
>> > private members of a class inside the same module is a 
>> > mistake because it breaks the idea of encapsulation. Unit 
>> > testing must be done exclusively on public members of a 
>> > class. If you are feeling the urge to test a class private 
>> > thing, there is something wrong with your class design. In 
>> > the parallel world of true OOP which D tries to avoid as 
>> > much as possible there is a saying for that: "Everytime you 
>> > test a private method, a unicorn dies".
>> 
>> I completely disagree with this. Testing private functions can 
>> be extremely valuable for ensuring that everything within the 
>> type functions the way that it should and can often lead to 
>> much better testing of how pieces of a type work, because you 
>> have better control over what's going on at that exact point 
>> in the call chain when you're testing it directly.
>
> Yeah, in my own projects I have found that unittesting private 
> functions has been a life-saver in catching bugs early 
> (especially if you're writing a complex class / struct / type / 
> module with many moving parts), ensuring helper functions 
> actually work, and also building confidence that the code is 
> actually doing what you think it's doing. Testing only the 
> external API means I have to write a ton of code before a 
> single test can be run, which means a lot more places for bugs 
> to hide and a lot more time wasted trying to locate a bug 
> buried deep within several levels of function calls under the 
> public API.
>
> If it's true that a unicorn dies everytime I test a private 
> method, then I say, kill 'em all off, they deserve to go 
> extinct!
>
> (None of this negates the fact that public APIs need to be 
> thoroughly tested, of course.  Like Jonathan, I just don't see 
> how one could argue that private methods should *not* be 
> tested.)
>
>
> T

I never said that. Feel free to test your private methods as long 
as you want it if you think that will improve your code 
correctness. But for *me* this is a bad practice. Every time I am 
in a situation that will result in such need, I question myself 
if there is something wrong with my class design and usually I 
end with extracting that private functionality to another class 
that can be tested.

Testing private functionality means that you *lock* the internal 
implementation of your class. If you decide later to change the 
implementation, your previous tests will have zero-value.

On the contrary, testing public functionality of a class will 
*lock* the design and this is desirable at least from a library 
design point of view.

The difference here is that D is offering you the means to code 
your stuff exactly as you want it, but the same is not true for 
my way of coding. And this is really annoying when you are doing 
TDD where the public testing of a class is in fact the definition 
of functionality and I don't want to touch by mistake any private 
member in the process.

class SquareRoot
{
   private void someComplicatedAlgorithm { ... }
   public void calculate() { ... someComplicatedAlgorithm() ... }
}

unittest
{
   //assert something about someComplicatedAlgorithm....
   //and so on.
}


Let's suppose that one day I will change someComplicatedAlgorithm 
and most of the assertions will not be satisfied. That moment I 
have two options: modify all my assertions to match or completely 
delete them, hence the zero-value of them.

It will not be better to limit my assertions to calculate() 
instead?







More information about the Digitalmars-d mailing list