17 Stimmen

Private Funktionen in Javascript testen

Ich verwende das Modulmuster in Javascript, um meine öffentliche Schnittstelle von der privaten Implementierung zu trennen. Um meine Arbeit zu vereinfachen, erzeugt mein Code ein Diagramm. Das Diagramm besteht aus mehreren Teilen (Achsen, Beschriftungen, Darstellung, Legende usw.) Mein Code sieht wie folgt aus:

var Graph = function() {
  var private_data;
  function draw_legend() { ... }
  function draw_plot() { ... }
  function helper_func() { ... }
  ...

  return {
    add_data: function(data) {
      private_data = data;
    },
    draw: function() {
      draw_legend()
      draw_plot()
    }
  }
}

Einige Leute plädieren dafür, nur die öffentliche Schnittstelle Ihrer Klassen zu testen, was auch Sinn macht, aber ich würde wirklich gerne einige Tests einbauen, um jede der Komponenten separat zu testen. Wenn ich meine draw_legend()-Funktion versaue, möchte ich, dass dieser Test fehlschlägt und nicht ein Test für die öffentliche draw()-Funktion. Bin ich hier auf dem falschen Weg?

Ich könnte jede der Komponenten in verschiedene Klassen aufteilen, z. B. eine Klasse Legende erstellen. Aber es scheint dumm, eine Klasse für das, was manchmal nur 5-10 Zeilen Code ist, zu erstellen, und es wäre hässlicher, weil ich in einem Bündel von privaten Zustand übergeben müssen würde. Und ich wäre nicht in der Lage, meine Hilfsfunktionen zu testen. Sollte ich das trotzdem tun? Sollte ich es auf sich beruhen lassen und nur die öffentliche draw() testen? Oder gibt es eine andere Lösung?

9voto

Helgi Punkte 1557

Es gibt keine Möglichkeit, von einem äußeren Bereich aus auf innere (private) Funktionen zuzugreifen. Wenn Sie innere Funktionen testen möchten, sollten Sie eine öffentliche Methode nur zu Testzwecken hinzufügen. Wenn Sie eine Art von Build-Umgebung verwenden, zum Beispiel Ant, können Sie die Javascript-Datei für die Produktion vorverarbeiten und diese Testfunktionen entfernen.

Eigentlich ist Javascript eine objektorientierte Sprache. Es ist nur keine statisch typisierte Sprache.

5voto

takacsot Punkte 1649

Meine Lösung ist nur ein kleines bisschen Hacken. QUnit Beispiel:

Am Anfang von Qunit test html habe ich deklariert:

var TEST_AVAILABLE = true;

In der testbaren Klasse habe ich ein Fragment wie dieses:

if(TEST_AVAILABLE){
   this.test={
      hasDraft:hasDraft,
      isInterpIdIn:isInterpIdIn,
      // other private methods
   };
}

In der QUnit können Sie Folgendes überprüfen

test( "hello booth", function() {
  var b = new Booth();
  ok(b);
  ok(b.test);
  ok(!b.test.hasDraft());
});

3voto

Karlo Ibarra Punkte 31

Ich habe ein ähnliches Problem. Die Lösung, die ich mir ausgedacht habe, gefällt mir zwar nicht, aber sie erfüllt ihren Zweck, und eine bessere Lösung habe ich nicht gefunden.

function Graph()
{
    this.Test = function _Test(expressionStr) { return eval(expressionStr); }

    var private_data;
    function draw_legend() { ... }
    function draw_plot() { ... }
    function helper_func() { ... }
    ...
}

Zum Testen:

var g = new Graph();
g.Test("helper_func()") == something;
g.Test("private_data") == something2

1voto

Sjeiti Punkte 2187

Es gibt tatsächlich einen einfachen Weg. Sie können Ajax verwenden, um das Skript zu laden und eine Funktion zu injizieren, die die privaten Funktionen offenlegt. Ich habe ein Beispiel ici das qUnit und jQuery verwendet. Aber ich bin sicher, dass dasselbe leicht mit reinem Javascript erreicht werden kann.

0voto

Chase Seibert Punkte 15327

In einer objektorientierten Sprache würden Sie in der Regel die Unit-Tests der geschützt Methoden, indem die Testklasse von der Klasse erbt, die sie testet.

Natürlich ist Javascript nicht wirklich eine objektorientierte Sprache, und dieses Muster erlaubt keine Vererbung.

Ich denke, Sie müssen entweder Ihre Methoden öffentlich machen, oder aufgeben, sie zu testen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X