Sinon.js stub und test externe Funktion aufrufen, die mit object als parameter später geändert durch ref

Bin ich suchen, um den Anruf meiner Funktion zu einer anderen Funktion, insbesondere ein argument, das ein Objekt ist.

Das Problem ist, dass sinon.js scheint zum speichern eines Verweises auf das Objekt-parameter in der arguments-array, das ist natürlich zu erwarten. Dies führt aber zu einem problem, wenn der parameter später geändert durch ref, welche Veränderungen die offensichtlich Wert dieser Parameter zum Zeitpunkt die Funktion aufgerufen wurde.

Was ist der beste Weg, um unit-test eine situation wie diese?

Ist hier ein erfundenes Beispiel:

http://jsfiddle.net/xtfQu/

var view = Backbone.View.extend({
    initialize: function () {
        _.bindAll(this);    
    },

    dostuff: function () {
        var coords = { x: 0, y: 0 };
        for (var i = 0; i < 10; i++) {
            this.otherstuff(coords);

            coords.x += 10;
        }
    },

    otherstuff: function (coord) {
        //Stubbed
    }
});

test("a test", function() {
    //Arrange
    var blah = new view();

    sinon.stub(blah, 'otherstuff');

    //Act
    blah.dostuff();

    //Assert
    var expectedFirstCallCoords = { x: 0, y: 0 };

    //All assertions on the value of x for a particular call would seem to be impossible.
    //blah.otherstuff.firstCall.args[0].x --> 100
    deepEqual(blah.otherstuff.firstCall.args[0], expectedFirstCallCoords, 'parameter changed by ref, untestable?');
});​

Ich denken kann von verschiedenen hacks, um dieses 'Problem'. Ist es ein sauberer Ansatz, der sich nicht um das Klonen des Objekts oder das ändern meiner Produktion code einfach im Interesse der immer sinon zu arbeiten?

  • Das sieht wie ein Fehler in Sinon. Es sollte wohl Klonen die Argumente, zumindest wenn Sie systemeigene Objekte. Haben Sie gefragt, in Ihre mailing-Liste? Christian könnte entweder einen work-around, oder in der Lage sein, um es patchen schnell. Oder könnte er auch in der Lage, empfehlen eine andere Technik. Ich kann nicht sehen, was nicht ziemlich aufdringlich.
  • Danke für die Bestätigung, ich bin nicht verrückt. 🙂 Das einzige Problem, mit sinon Klonen dieser Objekte ist, dass die tests mit strictEquals fehl gegen Sie. Wenn ich behauptet statt: strictEquals(blah.otherstuff.firstCall.args[0], expectedFirstCallCoords) würde scheitern, gegen einen Klon. In meinem erfundenen Beispiel, das ist kein Problem, aber was, wenn expectedFirstCallCoords injiziert wurden, die in der Funktion/Klasse? Das wäre sehr erwünscht. Im besten Fall, dass ich sehen kann, eh, ist, dass Sie brauchen, um zu speichern ursprüngliche Objekt verweist, und die geklonten Objekte, und das wäre verwirrend.
  • Ja, ich habe nicht betrachten Sie strictEquals. (Verwenden Sie, dass in der Prüfung? Ich nie tun.) Sehe ich nicht wirklich eine tolle Lösung für dieses. Aber als Bestätigung, dass Sie nicht verrückt, ich werde verlassen, dass zwischen Ihnen und Ihrem verkleinern! 🙂 Viel Glück!
  • Ich persönlich halte die Verwendung von equal werden schlechte Praxis. Sollten Sie beim testen sind Ihre Werte, die equal(true, 1); geht.
  • Ich benutze meistens JSTestDriver, und die Behauptung framework assertEquals ist eine Tiefe equals vergleichen, nicht aber ein Referenz-Vergleich. Ich glaube nicht, verwenden assertSame, oder nicht oft, das ist ein Referenz-Vergleich. Aber ich habe auch, z.B., assertTrue, assertNotNull, um sich bestimmte Arten. Auf der anderen Seite, habe ich oft wollen alle truthy Wert, um an meinem booleschen tests, wir haben also sehr unterschiedliche standards! 🙂
  • Solange Sie equal mit dem wissen, dass es in der Tat ist truthy das ist natürlich genau das, was es ist! Ich möchte nur zu zeigen :). Auch die Sache, die ich testete in meinem equal(true, 1) war kein boolean, sondern 1, so erwartet einen integer und übergeben einen test, wenn ich tatsächlich wieder einen Wahrheitswert (boolean oder string) scheint mir falsch zu sein. Für die meisten boolean Fälle, wo ich nur Sorge um truthy, das ist, wenn ich ok(). Ergebnis, dass ich jetzt darüber nachdenke, habe ich nie verwenden equal. 🙂 Aber das ist einfach, ich gebe zu, persönliche Präferenz. Nette Diskussion!

InformationsquelleAutor Adam Terlson | 2012-10-15
Schreibe einen Kommentar