2013-09-27 21 views
28

Voglio testare la mia app angolare con goniometro. L'app ha un modulo API che comunica con il server Durante questi test voglio prendere in giro questo modulo Api. Non voglio eseguire test di integrazione completi, ma test dall'input dell'utente con i valori previsti dall'API. Non solo questo potrebbe rendere più veloci i test del client, ma mi permetterebbe anche di testare i casi limite, come gli errori di connessione.Mocking e Stubbing con goniometro

Come posso fare questo con il goniometro? Ho appena iniziato a configurare i test di integrazione.

Ho utilizzato il modulo del goniometro npm, il selenio installato, ho regolato la configurazione di default e ho usato il onProtractorRunner.js per verificare che il mio setup funzioni.

Qual è il modo consigliato di prendere in giro? Suppongo che il mocking debba essere fatto all'interno del browser e non direttamente nel file di test. Suppongo che i comandi nel file di test siano specifici del goniometro e che vengano inviati ai corridori di selenio. Pertanto non posso condividere oggetti javascript durante la sessione e il test.

In qualche modo mi aspetto che avrò bisogno di una libreria di spie come sinon.js o è già inclusa nel goniometro?

Modifica: Ho letto circa this issue in the protractor issue tracker, che potrebbe essere un modo per farlo. Fondamentalmente si scrive un modulo Mock nel test, che viene inviato per essere eseguito nel browser/nell'ambito delle applicazioni.

Modifica: Ecco i problemi più promettenti. Il primo parla di adding Mocks to the Angular App. Il secondo parla di mocking the backend.

Questo sembra davvero bello, in questo caso l'App Angolare rimarrebbe nella sua forma originale. Tuttavia questo attualmente funziona solo con gli scenari ng deprecati.

+0

Hai trovato una soluzione nel frattempo? Ho avuto un po 'lo stesso problema, vedi http://stackoverflow.com/questions/21727053/angularjs-protractor-e2e-mocking –

risposta

0

Il punto di esecuzione dei test end-to-end con il goniometro consente di verificare che l'applicazione funzioni nell'integrazione. Se stai provando a testare i tuoi elementi dell'interfaccia utente in modo isolato, è più facile utilizzare piccoli elementi da test normali. Esattamente come lo stesso AngularJS verifica le direttive.

Detto questo, se vuoi davvero prendere in giro, un modo è creare una build separata della tua applicazione con stub invece di servizi reali.

2

Anche se io non ho provato io stesso a questo punto, angolare offre un $ finto httpBackend per le prove E2E:

http://docs.angularjs.org/api/ngMockE2E/service/$httpBackend

Così, prendendo dalla pagina di documentazione di cui sopra, ho il sospetto è possibile utilizzare qualcosa come la seguente prima che i test

beforeEach(function() { 
    $httpBackend.whenGET('/remote-url').respond(edgeCaseData); 
}); 
+3

Attualmente sto tentando di farlo nel mio file di prova e2e, ma non so come ottenere una sospensione di '' '$ httpBackend'''. Poiché '' 'inject()' '' non è disponibile nel goniometro. –

+1

Questo non funzionerà, non si ha accesso a $ httpBackend nella specifica del goniometro – jvans

+0

Questo funziona solo se si è configurato il proprio html per avere un'app ng che punti al modulo mocked. Non una soluzione – randominstanceOfLivingThing

1

ho creato un piccolo modulo di finto personalizzabile per aiutarmi a gestire gli scenari di successo e di errore, forse vi aiuterà a organizzare al meglio il beffardo.

https://github.com/unDemian/protractor-mock

+0

È ancora mantenuto? – stackular

+1

Sì, sto preparando una nuova versione per unificare i dati di unità e e2e mocking. – unDemian

+5

Per la cronologia, il modulo è stato deprecato dal suo autore. – rixo

8

This blog post discute scenari di utilizzo anticipati per goniometro. In particolare copre il poco conosciuto metodo addMockModule() dell'oggetto browser Goniometro.Il metodo consente di creare moduli angolari in Protractor (ovvero mazze o stub del modulo API) e caricarli nel browser per sostituire l'implementazione reale nel contesto di una determinata specifica o di una serie di specifiche.

1

Ho cercato di prendere in giro alcuni servizi in goniometro, e dopo aver visto alcuni blog sono arrivato a una soluzione che funziona per me. L'idea non è quella di fare sbeffeggiamenti pesanti, ma solo generare alcune risposte di errore; dato che per le fixture ho già una backdoor nel mio server API per popolare il back-end.

Questa soluzione utilizza lo $provide.decorator() per modificare solo alcuni metodi. Ecco come viene usato nelle prove:

it('should mock a service', function() { 
    app.mock.decorateService({ 
     // This will return a rejected promise when calling to "user" 
     // service "login()" method resolved with the given object. 
     // rejectPromise() is a convenience method 
     user: app.mock.rejectPromise('login', { type: 'MockError' }), 

     // You can decorate the service 
     // Warning! This code get's stringified and send to the browser 
     // it does not have access to node 
     api: function ($delegate, $q) { 
      $delegate.get = function() { 
       var deferred = $q.defer(); 

       deferred.resolve({ id: 'whatever', name: 'tess' }); 

       return defer.promise; 
      }; 

      return $delegate; 
     }, 

     // Internally decorateService converts the function to string 
     // so if you prefer you can set an string. Usefull for creating your 
     // own helper methods like "rejectPromise()". 
     dialog: [ 
      "function ($delegate, $window) {", 
       "$delegate.alert = $window.alert;", 
       "return $delegate;", 
      "}" 
     ].join('\n') 
    }); 

    // ... 

    // Important! 
    app.mock.clearDecorators(); 
}); 

Ecco il codice:

App.prototype.mock = { 
    // This must be called before ".get()" 
    decorateService: function (services) { 
     var code = [ 
      'var decorer = angular.module("serviceDecorator", ["visitaste"]);', 
      'decorer.config(function ($provide) {' 
     ]; 

     for (var service in services) { 
      var fn = services[service]; 

      if (_.isFunction(fn)) { 
       code.push('$provide.decorator("'+ service +'", '+ String(fn) +');'); 
      } else if (_.isString(fn)) { 
       code.push('$provide.decorator("'+ service +'", '+ fn +');'); 
      } 
     } 

     code.push('});'); 

     browser.addMockModule('serviceDecorator', code.join('\n')); 
    }, 
    clearDecorators: function() { 
     browser.clearMockModules(); 
    }, 
    rejectPromise: function (method, error, delay) { 
     return [ 
      'function ($delegate, $q) {', 
       '$delegate.'+ method +' = function() {', 
        'var deferred = $q.defer();', 
        '', 
        'setTimeout(function() {', 
         'deferred.reject('+ JSON.stringify(error) +');', 
        '}, '+ (delay || 200) +');', 
        '', 
        'return deferred.promise;', 
       '};', 
       '', 
       'return $delegate;', 
      '}' 
     ].join('\n'); 
    } 
}; 
0

Qui ci sono un paio di opzioni per stub server HTTP:

  • Stubby un piccolo web server con supporto di node, .Net e Java. Ne avrai bisogno per l'installazione e l'hosting.
  • Apiary a servizio ospitato per creare API false. Puoi usarlo anche per creare documentazione API.
+0

Vorrei aggiungere [Stubby DB] (https://www.npmjs.com/package/stubby-db) nel tuo elenco basato sul nodo e in grado di fornire una risposta statica e completamente dinamica. –

4

Non si ha accesso a $ httpBackend, controller o servizi dall'interno di un test del goniometro, quindi l'idea è di creare un altro modulo angolare e includerlo nel browser durante il test.

beforeEach(function(){ 
    var httpBackendMock = function() { 
     angular.module('httpBackendMock', ['ngMockE2E', 'myApp']) 
     .run(function($httpBackend) { 
      $httpBackend.whenPOST('/api/packages').respond(200, {}); 
     }) 
    } 
    browser.addMockModule('httpBackendMock', httpBackendMock) 
    }) 

ngMockE2E consente di creare un'implementazione di backend falso per l'applicazione. Ecco un post più approfondito sull'argomento http://product.moveline.com/testing-angular-apps-end-to-end-with-protractor.html