Sinon: Das Verketten von sinon.stub() mit mehreren .withArgs beendet nur die letzte Deklaration

Erstellt am 25. Sept. 2012  ·  23Kommentare  ·  Quelle: sinonjs/sinon

Das Verketten von sinon.stub() mit mehreren .withArgs beendet nur die letzte Deklaration

var stubbedFunction = sinon.stub().withArgs(argument1).returns(value1).withArgs(argument2).returns(value2);

dann wird nur die letzte Deklaration (.withArgs(argument2).returns(value2)) tatsächlich gestubbt

Hilfreichster Kommentar

Dies funktioniert ordnungsgemäß mit Sinon 1.7.3:

var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
s(1); // -> 'a'
s(2); // -> 'b'
s(3) // -> undefined

Alle 23 Kommentare

Sie müssen withArgs veranlassen, den ursprünglichen Stub, aus dem er erstellt wurde, zu ändern und zurückzugeben, sofern verfügbar.

+1 Dafür. In einem ähnlichen Zusammenhang möchte ich, dass withArgs optional den Durchgang zur ursprünglichen Methode für nicht übereinstimmende Argumente ermöglicht.

Wenn ich beispielsweise die Node.js-Methode fs.readFileSync() stubben möchte, möchte ich, dass Sinon die ursprüngliche Implementierung beibehält, damit require() (das readFileSync verwendet) nicht beschädigt wird. Verwenden Sie für meine Tests jedoch die Stubb-Methode für eine bestimmte Datei.

Beispiel für den vorherigen Kommentar:

beforeEach(function() {
  global.fs = require('fs');
  sinon.stub(fs, 'readFileSync').onlyWithArgs('my-file.txt').returns('Contents of file');

  // Then require the module under test, which uses fs.readFileSync() internally
  // require() uses original method with correct calling context
  global.myModule = require('../src/my-module');
});

afterEach(function() {
  fs.readFileSync.restore();
});

it('does something with the file', function() {
  expect(myModule.loadFromFile()).toEqual('Contents of file');
});

Ich möchte vorschlagen, dass @froots obiger Beitrag irgendwo in den Dokumenten gepostet wird. Ich habe lange gesucht, bevor ich diese Lösung gefunden habe, wie man Dateien mockt, die andere Abhängigkeiten über require enthalten

Gute Idee. Willst du es versuchen? http://github.com/cjohansen/sinon-web/

Dies funktioniert ordnungsgemäß mit Sinon 1.7.3:

var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');
s(1); // -> 'a'
s(2); // -> 'b'
s(3) // -> undefined

Ich denke nicht, dass dies ein Beispiel dafür ist, dass es funktioniert, da es immer noch nicht verkettet ist (Sie müssen den ursprünglichen Stub / Mock verwenden).

Wahr. Aber es ist gut genug und es macht deutlich, was los ist. Die Verkettung lässt Interpretationsspielraum.

Ich stimme @mantoni zu. Der Stub dient dazu, die vertragliche Antwort des Dienstes/der Anfrage anzuzeigen. Dieser Stil drückt das besser aus.

Ich denke, die Dokumentation könnte hier wahrscheinlich verbessert werden.

Ich hatte erwartet, dass Folgendes funktioniert:

var someObj = {
    someProp: sinon.stub().withArgs("foo").returns(true)
}

Es hat offensichtlich nicht wie beabsichtigt funktioniert. Aber was noch wichtiger ist, es ist nicht richtig fehlgeschlagen. Anstatt dass someObj.someProp nicht true zurückgibt, wenn foo nicht angegeben ist, hat es immer true zurückgegeben. Da die Klausel returns eine Verhaltensinstanz zurückgibt, gibt someObj.someProp true zurück.

Ich verstehe die Gründe für die Verkettungsstruktur, die verschiedene Arten von Objekten zurückgibt. Die Benutzer werden jedoch in die Irre geführt, was diese zurückgegebenen Objekte sind. Da die Methoden, die CallObjects und Behaviors exponieren, mit der von Stubs bereitgestellten API übereinstimmen, ist es leicht einzusehen, warum man annehmen sollte, dass es sich um Stubs handelt.

Ich stimme @jasonkarns zu. Ich bin gerade in dieselbe "Falle" getappt: Das Einfügen der Stub-Deklaration gibt nicht die erwartete Stub-Instanz zurück. Die Verkettung scheint jedoch wie erwartet zu funktionieren, wenn Mocks verwendet werden:

var someObj = {
    someProp: sinon.mock().withArgs("foo").returns(true)
}

Gibt es dafür einen Grund?

Ich bin mir nicht sicher, ob ich etwas vermisse, aber ist @froots point jetzt möglich? Musste das machen:

sinon.stub(fs, 'readdirSync', (dir) => {
    if (dir === 'foo-path') {
        return [
            'my.js',
            'fake.js',
            'stuff.js'
        ];
    }

    return fsReaddir(dir);
});

Wollte sowas machen:

var myStub = sinon.stub(fs, 'readdirSync', fs.readdirSync);

myStub
    .withArgs('foo-path')
    .returns([
        'my.js',
        'fake.js',
        'stuff.js'
    ]);

Ich denke, das ist jetzt behoben, das Beispiel unten funktioniert wie beabsichtigt mit [email protected]

var Dummy = {
    doSomething: function(something) {
        return 'doing ...' + something;
    }
}

sinon.stub(Dummy, 'doSomething')
    .withArgs('sleep').returns('sleepy')
    .withArgs('eat').returns('eating');

console.log(Dummy.doSomething('sleep'));
console.log(Dummy.doSomething('eat'));

@valentin-radulescu-hs es scheitert auf meiner Seite immer noch mit 1.17.7 .
Es nimmt immer noch das neueste returns als einzigen Rückgabewert, unabhängig von withArgs (wie von @jasonkarns https://github.com/sinonjs/sinon/issues/176#issuecomment- 78191790).

Was für mich funktioniert, ist die Antwort von @mantoni https://github.com/sinonjs/sinon/issues/176#issuecomment -33636496, indem withArgs() nicht verkettet wird.

var s = sinon.stub();
s.withArgs(1).returns('a');
s.withArgs(2).returns('b');

@zurfyx läuft ihr auf Node oder im Browser? Welche Node/Browser-Version verwendest du? Ich bin mir nicht sicher, ob es wichtig ist, aber ich würde gerne versuchen, es auf meiner Seite zu replizieren.

Hey @valentin-radulescu-hs. Ich führe es auf Node aus und verwende babel-cli 6.22.2

  • Knoten 6.9.4
  • NPM 3.10.10

Entschuldigung für die späte Antwort

@zurfyx Ich habe versucht, die von Ihnen erwähnte Konfiguration mit demselben Code zu replizieren, den ich oben geschrieben habe, und er gibt wie erwartet sleepy und eating an die Konsole aus. Ich bin mir nicht sicher, warum es dir Probleme bereitet 😢

@zurfyx Nur um _absolut_ sicher zu sein, hast du das schon probiert?

grep version node_modules/sinon/package.json
rm -r node_modules
rm npm-shrinkwrap
npm install
grep version node_modules/sinon/package.json

Meistens habe ich Probleme, weil die Paketversion, die ich erwarte, nicht mit der installierten übereinstimmt.

@ fatso83 Es funktioniert auch nicht. Die Ausgabeversion grep ist immer noch 1.1.7.7 .

Dies ist mein vollständiger Test, falls es helfen kann:

  it('test', () => {
    const s = sinon.stub();
    s.withArgs('a').returns('1');
    s.withArgs('b').returns('2');

    console.info(s('c'));
  });

s('a') : '1'
s('b') : '2'
s('c') : undefined

  it('test', () => {
    const s = sinon.stub()
      .withArgs('a').returns('1')
      .withArgs('b').returns('2');

    console.info(s('c'));
  });

s('a') : '2'
s('b') : '2'
s('c') : '2'

Ich kann dieses Verhalten auch reproduzieren, indem ich sinon.createStubInstance verwende.

const stub = sandbox.stub();
      const myObj = function(){};
      const objOne = sinon.createStubInstance(myObj);
      const objTwo = sinon.createStubInstance(myObj);
      stub.withArgs(objOne).returns('1');
      stub.withArgs(objTwo).returns('2');

      console.info(stub(objOne));
      console.info(stub(objTwo));

Ausgabe:
2 2

Ich dachte, sinon.createStubInstance sollte ein neues Stub-Objekt erstellen. Ist das falsch?

Ich bin mir nicht ganz sicher, ob diese Frage in diesen Thread gehört, aber es hat definitiv etwas damit zu tun. In einem Projekt mit sinon 1.17.7 habe ich mehrere withArgs -Anweisungen verkettet, wobei die letzte ein "Grab-All"-Matcher war, der als Standard diente. Zum Beispiel:

const s = sinon.stub();
s.withArgs(1).returns(1)
 .withArgs(2).returns(2)
 .withArgs(sinon.match.any).returns('my-default-value')

s(1) // 1
s(5) // my-default-value

Jetzt verwende ich 4.1.3 und das Verhalten hat sich geändert, es gibt immer my-default-value zurück. War das beabsichtigt? Wenn ja, gibt es eine Möglichkeit, einen Standard-/Fallback-Wert in einer Kette von withArgs zu definieren?

Ich glaube nicht, dass eine Änderung jemals beabsichtigt war. Wenn Sie eine Lösung für das bereitstellen können
Rückfall fühlen Sie sich frei! Mit got kann ich helfen herauszufinden, wo es passiert ist
beschuldigen.

Den Mann. 15. Jan. 2018, 11.13 Uhr David García [email protected] :

Ich bin mir nicht ganz sicher, ob diese Frage zu diesem Thread gehört, aber es
hat bestimmt was damit zu tun. In einem Projekt mit sinon 1.17.7 I
verwendet, um mehrere withArgs-Anweisungen zu verketten, wobei die letzte a war
"Grab-All"-Matcher, der als Standard diente. Zum Beispiel:

const s = sinon.stub();s.withArgs(1).returns(1)
.withArgs(2).returns(2)
.withArgs(sinon.match.any).returns('my-default-value')
s(1) // 1s(5) // mein-Standardwert

Jetzt verwende ich 4.1.3 und das Verhalten hat sich geändert, es kehrt immer zurück
mein-standardwert. War das beabsichtigt? Wenn ja, gibt es eine Möglichkeit, a zu definieren
Standard-/Fallback-Wert in einer Kette von withArgs?


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/sinonjs/sinon/issues/176#issuecomment-357638653 , oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAluXMzqALJ0JlAM3hUaiK1SSyca9H74ks5tKyS4gaJpZM4AK2eu
.

>

[Bild: --]

Carl-Erik Kopseng
[Bild: https://]about.me/kopseng
https://about.me/kopseng?promo=email_sig&utm_source=email_sig&utm_medium=email_sig&utm_campaign=external_links

@fatso83 Ich habe es eingegrenzt, und anscheinend war es Absicht . Für mich fühlt es sich natürlicher an, in der letzten withArgs -Anweisung einen Fallback anzugeben, obwohl in diesem Fall einfach die Reihenfolge geändert und .withArgs(sinon.match.any) an die erste Position gesetzt wird, um das Problem zu lösen

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen