2012-10-10 23 views
12

Ho creato un wrapper di database per la mia applicazione, mostrato di seguito. Per testarlo, ovviamente vorrei sostituire la libreria del database attuale. Potrei creare una nuova classe che prende in giro il metodo query e prendere tutti gli input lì, ma usare sinon.js sembra più appropriato, ma come dovrei usarlo?
Le funzioni mock o stub di sinon.js cosa dovrei usare?Stub e/o simulazione di una classe in sinon.js?

wrapper = (function() { 

    function wrapper() {} 

    wrapper.db = require("database"); 

    wrapper.prototype.insertUser = function(doc) { 
    return this.db.query("INSERT INTO USERS..."); 
    }; 

    return wrapper; 

})(); 

risposta

6

È possibile utilizzare entrambi per quello.

Mock ha un comportamento ordinato previsto che, se non seguito correttamente, sta per darvi un errore.

A Stub è simile a un mock, ma senza l'ordine, quindi è possibile chiamare i metodi come si desidera. Nella mia esperienza non hai quasi mai bisogno di una finta.

Entrambi sostituiranno il metodo con un metodo vuoto o una chiusura se ne passi uno. Sarebbe qualcosa di simile:

stub = sinon.stub(wrapper , 'insertUser ', function() { return true; }); 

quindi si aggiunge il comportamento aspetta per verificare se ha successo.

Mi piace usare Jasmine con Jasmine-Sinon per verificare i test.

+0

Oh. Quindi sarebbe meglio stub il metodo 'insertUser' piuttosto che la chiamata' this.db' che 'insertUser' fa? – Industrial

+2

Dipende da cosa si sta testando, ma se si vuole verificare se insertUser sta inserendo nel DB che sarebbe un test di integrazione e nessuna stub verrebbe risparmiata dall'usare la logica reale con alcuni nel DB di memoria per "falsificare" un Oracle ad esempio, se vuoi verificare se l'insertUser viene chiamato quando necessario, il metodo insertUser di stub potrebbe essere un modo per farlo ... –

8

In primo luogo, mi piacerebbe modificare la vostra definizione di classe un po '(nome di classe maiuscole e risolvere db assegnazione):

var Wrapper = (function() { 

    function Wrapper() { 
    this.db = require("database"); 
    } 

    Wrapper.prototype.insertUser = function(doc) { 
    return this.db.query("INSERT INTO USERS..."); 
    }; 

    return Wrapper; 

})(); 

Per stub tutta la classe:

var WrapperStub = sinon.spy(function() { 
    return sinon.createStubInstance(Wrapper); 
}); 

sinon.createStubInstance sarà creare un'istanza di Wrapper in cui ogni metodo è uno stub. sinon.spy ci permetterà di spiare l'istanza della classe.

Così si potrebbe esercitare in questo modo:

// verify instantiation 
var wrapper = new WrapperStub(); 
expect(WrapperStub).to.have.been.calledWithNew; 

// verify method stub 
wrapper.insertUser.returns('data'); 
expect(wrapper.insertUser()).to.equal('data'); 
expect(wrapper.insertUser).to.have.been.calledOnce; 

(asserzioni utilizzare chai e sinon-chai)

ho appena detto "esercitarlo" perché questo frammento di codice non è un test vero e proprio. L'istanziazione e le chiamate al metodo saranno fatte dal soggetto in prova.

Ora, se si vuole prendere in giro una dipendenza iniettato da require() -come db = require('database') nel vostro esempio-, si potrebbe provare uno strumento di test come sia Jest (ma non tramite Sinon) oppure sinonquire che ho creato ispirato da Jest ma per usarlo con sinon plus il tuo strumento di test preferito (il mio è moka). Internamente, sinonquire utilizza la stessa tecnica sopra illustrata di combinare sinon.spy e sinon.createStubInstance per eseguire lo stub di una classe.

+0

Link aggiornati a Jest: https://facebook.github.io/jest/docs/mock -functions.html http://facebook.github.io/jest/docs/jest-object.html#jestenableautomock – jwadsack

Problemi correlati