생산자

원문 중에서

I'm just now learning TDD. It's my understanding that private methods are untestable and shouldn't be worried about because the public API will provide enough information for verifying an object's integrity.

I've understood OOP for a while. It's my understanding that private methods make objects more encapsulated, thus more resistant to change and errors. Thus, they should be used by default and only those methods that matter to clients should be made public.

Well, it's possible for me to make an object that has only private methods and interacts with other objects by listening to their events. This would be very encapsulated, but completely untestable.

Also, it's considered bad practice to add methods for the sake of testing.

Does this mean TDD is at odds with encapsulation? What is the appropriate balance?
I'm inclined to make most or all of my methods public now...

대답

6
Bad practice and reality in the software industry are different animals. An ideal situation is more often than not a distorted reality in the business world. Do what makes sense and stick to it throughout the application. I'd much rather have a bad practice in place than the flavor of the month spread across the application. – Aaron McIver yesterday
5
"private methods are untestable"? Which language? In some languages it's inconvenient. In other languages it's perfectly simple. Also, are you saying that the design principle of encapsulation must always be implemented with lots of private methods? That seems a bit extreme. Some languages don't have private methods, yet, still seem to have nicely encapsulated designs. – S.Lott yesterday
"It's my understanding that private methods make objects more encapsulated, thus more resistant to change and errors. Thus, they should be used by default and only those methods that matter to clients should be made public." This seems to me like counter point of view of what TDD is trying to achieve. TDD is development methodology that leads you to create simple, workable and open-to-changes design. Looking "from private" and "only publicize..." is turned around completely. Forget there is such a thing as a private method to embrace TDD. Later, do them as needed; as a part of refactoring. – herby 23 hours ago
Depending on your development environment, some of your assumptions may be flawed. I tried to explain fragments in a related question over on Software, Quality Assurance and Testing Stack Exchange, but my answer wasn't appreciated there. *8') – Mark Booth 23 hours ago

Of course you can have private methods, and of course you can test them.

Either there is some way to get the private method to run, in which case you can test it that way, or there is no way to get the private to run, in which case: why the heck are you trying to test it, just delete the damn thing!

In your example:

Well, it's possible for me to make an object that has only private methods and interacts with other objects by listening to their events. This would be very encapsulated, but completely untestable.

Why would that be untestable? If the method is invoked in reaction to an event, just have the test feed the object an appropriate event.

It's not about having no private methods, it's about not breaking encapsulation. You can have private methods but you should test them through the public API. If the public API is based on events, then use events.

For the more common case of private helper methods, they can be tested through the public methods that call them. In particular, since you are only allowed to write code to get a failing test to pass and your tests are testing the public API, all new code you write is usually going to be public. Private methods only appear as a result of an Extract Method Refactoring, when they are pulled out of an already existing public method. But in that case, the original test which tests the public method still covers the private method as well, since the public method calls the private method.

So, usually private methods only appear when they are extracted from already tested public methods and are thus already tested as well.