2016-07-11 18 views
3

Ich schreibe einige Tests für eine asynchrone Funktion node.js, die ein Versprechen unter Verwendung der Bibliotheken Mocha, Chai und Sinon zurückgibt.
Lassen Sie uns sagen, das ist meine Funktion:Aktivieren von Funktionsaufrufen in einem Versprechen

function foo(params) { 
    return (
    mkdir(params) 
    .then(dir => writeFile(dir)) 
) 
} 

mkdir & writeFile sind beide Asynchron-Funktionen, die Versprechungen zurück.
Ich muss testen, dass mkdir wird einmal mit der params an foo gegeben.

Wie kann ich das tun?
Ich habe einige Beispiele gesehen, wie man den gesamten Rückgabewert von foo (sinon-as-promised ist super hilfreich für das) aber nicht darüber, wie Sie sicherstellen, dass einzelne Funktionen innerhalb der Versprechen aufgerufen werden.

Vielleicht habe ich etwas übersehen und das ist nicht der richtige Weg?

+0

'mkdir' nicht in einem Versprechen genannt wird, ist es synchron von 'foo' genannt und Sie können es testen wie immer? Oder möchten Sie testen, dass 'writeFile' aufgerufen wird? – Bergi

Antwort

2

mkdir nicht asynchron hier genannt wird, so ist es ziemlich trivial zu testen:

mkdir = sinon.stub().resolves("test/dir") 
foo(testparams) 
assert(mkdir.calledOnce) 
assert(mkdir.calledWith(testparams)) 
… 

Falls Sie testen wollen writeFile genannt wurde, dass nur etwas komplizierter ist - wir müssen warten das Versprechen zurück von foo vor Geltendmachung:

… // mdir like above 
writeFile = sinon.stub().resolves("result") 
return foo(testparams).then(r => { 
    assert.strictEqual(r, "result") 
    assert(writeFile.calledOnce) 
    assert(writeFile.calledWith("test/dir")) 
    … 
}) 
0

Sie können die mkdir Funktion spötteln und dann setTimeout verwenden, um zu überprüfen, ob diese Funktion aufgerufen wird oder nicht.

describe('foo',() => { 
    it('should call mkdir',() => { 
    return new Promise((resolve, reject) => { 
     let originalFunction = mkdir; 
     let timer = setTimeout(() => { 
     reject(`mkdir has not been called`); 
     }); 
     mkdir = (...params) => new Promise(mkdirResolve => { 
     //restore the original method as soon as it is invoked 
     mkdir = originalMethod; 
     clearTimeout(timer); 
     mkdirResolve(someExpectedData); 
     resolve(); 
     }); 
     foo(params); 
    }); 
    }); 
}); 
+1

Noch besser: Verwenden Sie kein Timeout, sondern haken Sie einfach das Versprechen ein, das 'foo' zurückgibt. – Bergi

+0

@Bergi Ich denke das wäre eine interessante Antwort. – Lewis