2013-04-15 11 views
8

Come posso verificare questo in modo asincrono?Come testare uno stub che restituisce una promessa in un test asincrono?

it('Should test something.', function (done) { 

    var req = someRequest, 
     mock = sinon.mock(response), 
     stub = sinon.stub(someObject, 'method'); 

    // returns a promise 
    stub.withArgs('foo').returns(Q.resolve(5)); 

    mock.expects('bar').once().withArgs(200); 

    request(req, response); 

    mock.verify(); 

}); 

Ed ecco il metodo da testare.

var request = function (req, response) { 

    ... 

    someObject.method(someParameter) 
     .then(function() { 
      res.send(200); 
     }) 
     .fail(function() { 
      res.send(500); 
     }); 

}; 

Come potete vedere sto usando node.js, Q (per la promessa), Sinon per beffardo e lo sradicamento e moka come l'ambiente di test. Il test precedente non riesce a causa del comportamento asincrono dal metodo di richiesta e non so quando chiamare done() nel test.

+0

modo più semplice che ho trovato a lavorare con le chiamate asincrone, quando si desidera utilizzare la risposta, è stato quello di rompere la funzione 2 in corrispondenza del punto in cui è necessaria e chiamata la risposta la seconda parte quando viene ricevuta la risposta. –

+0

è necessario scegliere una risposta, non solo upvote. – oligofren

risposta

4

È necessario chiamare una volta terminate tutte le operazioni asincrone. Quando pensi che sarebbe? Come faresti normalmente aspettare fino a quando una richiesta è finita?

it('Should test something.', function (done) { 

    var req = someRequest, 
     mock = sinon.mock(response), 
     stub = sinon.stub(someObject, 'method'); 

    // returns a promise 
    stub.withArgs('foo').returns(Q.resolve(5)); 

    mock.expects('bar').once().withArgs(200); 

    request(req, response).then(function(){ 
     mock.verify(); 
     done(); 
    }); 

}); 

Potrebbe anche essere una buona idea per contrassegnare il test in quanto non in un errorcallback allegato alla richiesta promessa.

+0

Il metodo di richiesta non è una promessa per sé. Quindi non c'è nessun metodo da chiamare. Aspetterei fino a quando non si chiamerà response.send. Sfortunatamente il metodo di richiesta termina prima che ciò accada. – Stefan

+1

Forse il nocciolo di questo problema non è venuto fuori tranquillo. Di solito cedo il callback da someObject.method come in questo modo 'stub.withArgs ('foo'). Yields (5)'. In questo caso la funzione di callback viene eseguita immediatamente. Ma ora, con le promesse, restituisco solo un oggetto posticipato e il gestore di risoluzione e rifiuto viene richiamato fino a tardi perché il metodo di richiesta è già terminato. Pertanto gli oggetti fittizi non sono stati verificati. Se avvolgo il metodo di verifica in un setTimeout con una chiamata a termine, il test passa. 'setTimeout (function() {mock.verify(); done();}, 100)' – Stefan

+0

Hmm, nella mia esperienza è una buona pratica per i metodi asincroni fornire un modo per sapere quando verranno completati - per fare ciò è possibile o accetta un parametro di callback o restituisce una promessa. A seconda del metodo che usi, puoi chiamare il codice "end of test" lì. –

1

Soluzione di lavoro a macchina:

var returnPromise = myService.method() 
    returnPromise.done(() => { 
     mock.verify() 
    }) 
Problemi correlati