JUnit testen einer private Methode

OnDemand

Top Contributor
Hallo zusammen,

möchte mich mal ans testen wagen.

Habe einen Service welcher einen Server anlegt und danach eine Methode aufruft welche den Emailversand triggert.

DummyCode:
Java:
@Service
public class ServerService {

    public void createServer(){
        //bestellt server
        sendLoginDataCustomerPortal(User user)
    }
  
    private void sendLoginDataCustomerPortal(user){
        //sendet Mail diese Methode möchte ich testen
    }

Java:
class ServerServiceTest {

    @Autowired
    ServerService serverService;

    @Test
    void createServer() {
        ContractPartner contractPartner = new ContractPartner();
        serverService.sendLoginDataCustomerPortal(contractPartner); //geht nicht weil og Methode private ist
    }
}

Irgendwie muss ich mal langsam einsteigen, das ist glaube ein gutes Beispiel. Wer kann mir erklären was man machen muss, damit das sauber funktioniert?
Die ServerService Klasse auch einen Test in dem Testpackage anlegen? IntelliJ schlägt mir vor "make ServerService.sendLoginDataCustomerPortal package-private" was hat es damit auf sich?
 
In einem Test musst Du die Methode aufrufen. Das ist aber schwer, wenn diese private ist. (Per Reflection würde das zwar gehen, aber das ist ja nicht Sinn der Sache!)

Wenn Du es nun package private machst (also ohne Modifizierer), dann kann aus dem Package auf die Methode zugegriffen werden. Somit kann eine Testklasse, die im gleichen Namespace ist, die Methode aufrufen.
 
Wenn die Methode private ist, sollte sie durch Aufrufe der public Methode schon getestet sein. Wenn da irgendein Service aufgerufen wird, kannst du den mocken und den Aufruf verifien. Modifier ändern oder gar mit Reflection rangehen, würde ich nicht empfehlen.
 
Die reine Lehre sagt - private Methoden werden nicht getestet, die werden über die Public API mit getestet. Wenn man Bedarf hat eine private Methode zu testen, ist das fast immer ein Zeichen, dass die Architektur nicht ideal ist. Denn dann macht die private Methode zu viel. Eine public API sollte immer sinnvoll und knapp beschreibbar sein ohne das ich Doku von privaten Methoden brauche. Das heißt, die Beschreibung was sendLoginDataCustomerPortal gehört in die Beschreibung der Methode createServer rein - was dann bedeutet, dass die Methode createServer anscheinend zu viel macht. Das heißt, die beste Idee ist das umzubauen. Wie genau, kann man jetzt schlecht sagen.

Soweit die reine Lehre. In der Praxis kann man die nicht immer zu 100% befolgen, seien es Zeitgründe, seien es Legacy-Systeme die man nicht ändern kann/darf, seien es Fehler in der Vergangenheit die nun zu teuer sind zu ändern etc. Dann macht man manchmal die Methode soweit sichtbar, dass sie von Tests, die im selben Package liegen, aufgerufen werden können. Also entweder package private oder protected (gerne auch final, damit keine auf die Idee kommt bei einer Ableitung sie zu überschreiben). Wenn man google guava nutzt, gibt es für sowas sogar eine Annotation: VisibleForTesting: https://guava.dev/releases/19.0/api/docs/com/google/common/annotations/VisibleForTesting.html um das explizit zu dokumentieren. Nicht der schönste Weg, aber manchmal geht halt der schönste Weg nicht.
 

Zurück
Oben