junit-team / junit5

✅ The 5th major version of the programmer-friendly testing framework for Java and the JVM
https://junit.org
Eclipse Public License 2.0
6.44k stars 1.5k forks source link

Document which classes support inheritance and which do not #938

Open jbduncan opened 7 years ago

jbduncan commented 7 years ago

Overview

Currently, AFAICT, no classes (apart from utilities classes) document their support for inheritance (that is, whether they are designed to be subclassed or not). Effective Java 2nd edition, Item 16 describes the dangers of allowing users and extension writers to subclass JUnit 5 classes that aren't designed for inheritance. Therefore we should follow Item 17's advice to prevent this.

Specifically, each class should meet the following criteria (more or less ripped from the book):

  1. For classes that support inheritance:
    1. Make those methods which aren't intended to be overridden final.
    2. The class must document it's self-use of overridable methods.
    3. To allow programmers to write efficient subclasses without undue pain, a class may have to provide hooks into its internal workings in the form of judiciously chosen protected methods or fields.
    4. The only way to test a class designed for inheritance is to write subclasses; classes must be tested by writing subclasses before releasing it. (Before GA, in our case.)
    5. Constructors must not invoke overridable methods.
    6. For classes implementing Cloneable or Serializable, neither clone nor readObject may invoke an overridable method, directly or indirectly.
  2. For classes that don't support inheritance:
    1. Prohibit subclassing by making the class final or replacing all public constructors with public static factory methods.

Deliverables

sbrannen commented 7 years ago

slated for RC1 for team discussion

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. Given the limited bandwidth of the team, it will be automatically closed if no further activity occurs. Thank you for your contribution.

jbduncan commented 3 years ago

I'd still like for this to be addressed at some point.

jbduncan commented 3 years ago

That being said, I understand if some classes/methods can't be made final now for backward-compatibility reasons, but at the very least each and every public class and method should be documented appropriately.

marcphilipp commented 3 years ago

We have done so in a few places, e.g.: https://github.com/junit-team/junit5/blob/17d3b440f3b6c3ba4616fc927e7782e74582ea86/junit-jupiter-params/src/main/java/org/junit/jupiter/params/aggregator/ArgumentsAccessor.java#L35 https://github.com/junit-team/junit5/blob/17d3b440f3b6c3ba4616fc927e7782e74582ea86/junit-platform-launcher/src/main/java/org/junit/platform/launcher/TestPlan.java#L52

@jbduncan Is this something you think you could contribute via a PR?

jbduncan commented 3 years ago

@marcphilipp Oh, excellent!

I've also seen that this file has some inheritance-related info:

https://github.com/junit-team/junit5/blob/419ddb12f13049692949f0f12d50e8f38cf43cba/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java#L82-L84

Yes, I'd love to raise a PR, but I'm currently juggling a PR for junit-pioneer and some real life commitments, so I've put this issue on my TODO list. :)

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. Given the limited bandwidth of the team, it will be automatically closed if no further activity occurs. Thank you for your contribution.

jbduncan commented 2 years ago

I'm still interested in contributing this eventually.

Basmalamoustafa commented 3 days ago

Hello @jbduncan , I would to work on this issue. Could you please assign it to me? Thank you!

jbduncan commented 3 days ago

@Basmalamoustafa Sure, please go right ahead!

As we can't make any backwards-incompatible changes now, I think the best approach is to do the following for as many non-final classes as you can find:

I hope this helps.