Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Unittests mit private Methoden

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Unittests mit private Methoden

    Hallo

    Ich kämpfe mal wieder damit herum, wie man in OOP etwas richtig programmiert.

    Ich habe folgende Klasse:
    PHP-Code:
    class X
    {
       private function 
    _algorithmus()
       {
          
    // hier passiert irgendetwas kompliziertes
       
    }
       public function 
    m()
       {
          
    // irgendwelche Befehle

          // dann kommt ein komplizierter Algorithmus:
          
    $this->_algorithmus(); // in einer eigenen Methode ausgelagert

          // dann kommen wieder irgendwelche Befehle
       
    }

    Hierin gibt es also die public Methode 'm()'. In dieser Methode stünde ein komplizierter Algorithmus. Um diesen jedoch extra gründlich mittels UnitTests prüfen zu können, ist er in einer eigenen Methode '_algorithmus()' ausgelagert. Diese darf dann nur private sein.

    Allerdings kann ich von außen nicht auf eine private Methode zugreifen. Ich kann also keine Unittests durchführen.

    Also müsste ich die private Methode entweder public machen oder eine zusätzliche public-Methode definieren, z. B.:
    PHP-Code:
    class X
    {
       private function 
    _algorithmus()
       {
          
    // hier passiert irgendetwas kompliziertes
       
    }
       public function 
    testAlgorithmus() // diese Methode ist dann nur für die Unit-Tests
       
    {
          
    // macht nur eines: es ruft die private Methode _algorithmus auf:
          
    $this->_algorithmus();
       }
       public function 
    m()
       {
          
    // irgendwelche Befehle

          // dann kommt ein komplizierter Algorithmus:
          
    $this->_algorithmus();

          
    // dann kommen wieder irgendwelche Befehle
       
    }

    Allerdings finde ich das auch nicht so toll. Gibt es vielleicht noch eine andere Lösung??

  • #2
    Eigentlich sollten private Methoden ja "versteckt" sein. Und deshalb sollten auch nur öffentliche Methoden getestet werden. Wenn du nämlich mal an deiner Implementierung was verändern willst bleibt vlt. das Verhalten nach außen gleich, alle Unittests würden also weiter durchlaufen, aber die internen Funktionen funktionieren möglicherweise anders. In deinem Fall würde dann doch der Unittest brechen.

    Falls du es trotzdem brauchst, was bei komplizierten Methoden vlt. doch sinnvoll sein könnte, dann probiers doch mit Reflection.

    PHP-Code:
    protected static function getMethod($name) {
      
    $class = new ReflectionClass('MyClass');
      
    $method $class->getMethod($name);
      
    $method->setAccessible(true);
      return 
    $method;
    }

    public function 
    testFoo() {
      
    $foo self::getMethod('foo');
      
    $obj = new MyClass();
      
    $foo->invokeArgs($obj, array(...));
      ...

    Kommentar


    • #3
      Bin eigentlich kein Fan von Reflection, ehrlich gesagt. Reflection sollte man meiner Meinung nach eher nur zu Dokumentationszwecken verwenden.

      Kommentar


      • #4
        Reflections sind genau für sowas gut. Unittests gehören ja nicht zur Anwendung selber. Und zum testen sind Reflections doch wie geschaffen dafür.

        Kommentar


        • #5
          OHHHH!!!!! Jetzt wird mir erst bewusst, was du da eigentlich machst. Du greifst dann von außen auf eine private-deklarierte Methode zu? Ich kann das leider nicht ausprobieren, weil ich nur 5.3.1 habe. Aber das ist ja echt arg! Da könnte ich ja rein theoretisch via Reflection auf jede beliebige private-Methode zugreifen. AU WEH! Was haben sich die PHP-Programmierer denn dabei gedacht.?.?.?

          Kommentar


          • #6
            Das hat nichts mit PHP zutun. Das gibts auch in anderen Sprachen (Java zum Beispiel). Reflections sind ein mächtiges Werkzeug grade um etwas zu debuggen oder zu testen. In der Anwendung selber solltest du eigentlich drauf verzichten und eben den normalen OOP Paradigmen gerecht werden. Aber eben genau so Dinge die nicht zur Anwendung gehören und komplett von außen (einmalig, also Debugging, Unittesting) getan werden ist das nen super Werkzeug.

            Und funktionieren Reflections nicht ab PHP 5 ?

            Kommentar


            • #7
              Ansonsten kann man die Klasse auch einfach noch einmal ableiten. Deshalb solltest DU wo möglich auch immer protected statt private verwenden.

              AU WEH! Was haben sich die PHP-Programmierer denn dabei gedacht.?.?.?
              Member visibility dient keinen Sicherheitsaspekten. Von daher ist da nichts schlimmes dran.

              Kommentar


              • #8
                setAccessible gibt es anscheinend erst ab 5.3.2

                Na OK. Also mit Reflections. Danke

                Kommentar


                • #9
                  Ab 5.3.0 steht doch im Manual oder?

                  Kommentar

                  Lädt...
                  X