18

Io uso John papà stile angolare guide mio controller appare come:Come testare il test dell'unità John papa vm.model con il gelsomino?

seguendo lo stile John papa style controller style guide:

function testController() { 

    var vm = this; 

    vm.model = { name: "controllerAs vm test" }; 
} 

Il mio codice di prova si presenta come:

describe('Controller: testController', function() { 

    beforeEach(module('myApp')); 

    var testController; 

    beforeEach(inject(function ($controller) { 
     scope = {}; 

     testController = $controller('testController', { 
     }); 

    })); 

    it('should have vm.model defined and testController.vm.model is equal to controllerAs vm test', function() { 
     expect(testController.vm).toBeDefined(); 
     expect(testController.vm.model).toBeDefined();  
     expect(testController.vm.model.name).toEqual("controllerAs vm test"); 
    }); 
}); 

Risultato:

test non riuscito: Messaggio risultato: Previsto indefinito da definire. allo stack

Quindi la mia domanda è come possiamo testare vm.model e altre variabili da questo? Non ho trovato corretto linea guida nelle linee guida: controllers

risposta

24

Il vm è uguale alla istanza stessa via vm = this;

Pertanto, tutte le proprietà sono appesi direttamente fuori dell'oggetto.

function foo(){ 
    var vm = this; 

    vm.name = 'Josh'; 
} 

var myFoo = new foo(); 
myFoo.name; // 'Josh'; 

Quindi, tutto quello che dovete fare è cambiare le vostre aspettative per rimuovere la proprietà vm.

expect(testController).toBeDefined(); 
expect(testController.model).toBeDefined();  
expect(testController.model.name).toEqual("controllerAs vm test"); 

Per dimostrare questo, qui è il vostro esempio esatto, e le prove di Jasmine associati.

function testController() { 
 

 
    var vm = this; 
 

 
    vm.model = { 
 
    name: "controllerAs vm test" 
 
    }; 
 
} 
 

 

 
angular.module('myApp', []) 
 
    .controller('testController', testController); 
 

 
describe('Controller: testController', function() { 
 

 
    beforeEach(module('myApp')); 
 

 
    var testController; 
 

 
    beforeEach(inject(function($controller) { 
 
    scope = {}; 
 

 
    testController = $controller('testController', {}); 
 

 
    })); 
 

 
    it('should have model defined and testController.model.name is equal to controllerAs vm test', function() { 
 
    expect(testController).toBeDefined(); 
 
    expect(testController.model).toBeDefined(); 
 
    expect(testController.model.name).toEqual("controllerAs vm test"); 
 
    }); 
 

 
    it('should not have a property called vm', function() { 
 
    expect(testController.vm).toBeUndefined(); 
 
    }); 
 
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.css" rel="stylesheet" /> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine-html.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/boot.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.4/angular.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.4/angular-mocks.js"></script>

+0

come funzione la risposta sembra ok ma qui il mio problema è quando inizializzo l'istanza del controller da: testController = $ controller ('testController', { }); quindi testController.vm dovrebbe funzionare ma non funziona.Quindi la mia domanda è ai ragazzi che hanno lavorato con il controller di angular john papa come sintassi vm e testato con jasmine. –

+0

@UtpalKumarDas - Sotto il '' controller 'di Hood sta chiamando 'new()', quindi funziona allo stesso modo. – Josh

+2

@UtpalKumarDas - Lavoro con Angular da diversi anni e ho fatto molti test con Jasmine. Sto cercando di spiegare che questa non è una cosa Angolare, ma una JavaScript. 'vm' non è una proprietà sul controller ... è una variabile che viene chiusa dall'ambito della funzione. Pertanto, ** mai ** esiste sul controller quando viene utilizzato in questo modo. '$ controller' non cambia il modo in cui JS funziona. – Josh

6

testControllerè il vm perché si imposta var vm = this nel controller. Quindi, per rendere il codice di prova più simile al codice di controllo, si può provare a impostare il controller per vm nel test troppo invece ditestController

describe('Controller: testController', function() { 
    // we work with "vm" instead of "testController" to have consistent verbiage 
    // in test and controller 
    var vm; 

    beforeEach(module('app')); 
    beforeEach(inject(function ($controller) { 
     vm = $controller('testController', {}, {}); 
    })); 

    it('should have vm.model defined and testController.vm.model is equal to controllerAs vm test', function() { 

     // vm=this in controller 
     expect(vm) 
      .toBeDefined(); 

     // Testing primitives 
     expect(vm.foo) 
      .toBeDefined(); 
     expect(vm.foo) 
      .toEqual('bar'); 

     // Testing objects 
     expect(vm.model) 
      .toBeDefined(); 
     expect(vm.model.name) 
      .toEqual("Batman"); 

     // Testing a method 
     expect(vm.greet()) 
      .toBeDefined(); 
     expect(vm.greet()) 
      .toEqual('Hello There'); 
    }); 
}); 

Codice per il controller

(function() { 
    'use strict'; 

    angular 
     .module('app') 
     .controller('testController', testController); 

    /* @ngInject */ 
    function testController() { 
     var vm = this; 

     // Primitives 
     vm.foo = 'bar'; 

     // Objects 
     vm.model = { 
      name: 'Batman' 
     }; 

     // Methods 
     vm.greet = function() { 
      return 'Hello There'; 
     }; 
    } 
})(); 

Spero che questo ti aiuti. In bocca al lupo.

1

Vorrei creare un nuovo modulo e iniettarlo come dipendenza nell'app modulo per renderlo semplice e verificabile. Test del controller con Style Guide di John Papa:

(function() { 
    'use strict'; 

    angular 
    .module('test') 
    .controller('testController', testController); 

    function testController() { 
    var vm = this; 
    vm.model = { name: "controllerAs vm test" }; 
    } 
})(); 

La specifica ora sarebbe simile a questa:

'use strict'; 

describe('testController', function() { 
    var testController; 
    beforeEach(module('test')); 

    beforeEach(function() { 
    inject(function($injector) { 
     testController = $injector.get('$controller')('testController', {}); 
    }); 
    }); 

    it('should have model defined and testController.name is equal to controllerAs vm test', function() { 
    expect(testController).toBeDefined(); 
    expect(testController.name).toEqual("controllerAs vm test"); 
    }); 
}); 

Spero che questo aiuti tutti coloro che cercano soluzioni simili.

Problemi correlati