2016-06-29 21 views
9

Sto provando a testare un controller (figlio) di un componente AngularJS 1.5 (con Webpack) che richiede un componente padre e un controller da un altro modulo.Controller di test angolare a 1,5 unità che richiede il controller del componente genitore

Bambino struttura di regolazione:

function ChildController() { 
    var vm = this; 

    vm.searchText = ''; 

    vm.submit = function() { 
    var data = {}; 
    data['srch'] = vm.searchText; 
    vm.parentCtrl.submitTextSearch(data); 
    }; 
} 

module.exports = ChildController; 

componente figlio:

var template = require('./child.html'); 
var controller = require('./child.controller'); 

var childComponent = { 
    require: { 
    parentCtrl: '^parent' 
    }, 
    template: template, 
    controller: controller, 
    controllerAs: 'vm' 
}; 

module.exports = childComponent; 

Quindi quello che vorrei fare è prendere in giro la parentCtrl che è richiesto a presentare() del childController - la funzione. Non sono stato in grado di trovare come farlo realmente. Ho trovato alcune soluzioni simili per la direttiva figlio-genitore e ho provato quelle, ad es. iniettare il controller genitore tramite un falso elemento HTML come descritto in this child-parent directive example e fondamentalmente lo stesso stackoverflow solutions senza risultati. I miei problemi differiscono almeno nel fatto che il controller figlio e genitore si trovano in moduli diversi. E suppongo che i trucchi di ambito non siano molto angolari in stile 1.5?

Lo scheletro del mio test Jasmine senza i miei tentativi falliti finte:

describe('child component', function() { 
    describe('child controller', function() { 
    var controller; 
    beforeEach(angular.mock.module('child')); 
    beforeEach(inject(function(_$componentController_) { 
     controller = _$componentController_('child'); 
    })) 
    it('should work', function() { 
     controller.searchText = "test"; 
     controller.submit(); 
    }) 
    }) 
}) 

che si traduce in TypeError: Cannot read property 'submitTextSearch' of undefined. Cosa dovrei fare esattamente per deridere il controllore genitore? Con la mia limitata esperienza in Angular, sono fuori di idee.

risposta

4

Nel tuo caso si aggiunge parentCtrl come dipendenza del componente, quindi per testarlo è necessario prendere in giro anche il componente padre e assegnarlo al controller. Così avresti bisogno di fare qualcosa di simile:

beforeEach(inject(function(_$componentController_) { 
    controller = _$componentController_('child'); 
    parentCtrl = _$componentController_('parent'); 
    controller.parentCtrl = parentCtrl; 
})) 
+0

Ho provato questo, ma non funziona per me. Ancora non è stato trovato "Controller '', richiesto dalla direttiva ''!". –

+1

Sei sicuro della tua configurazione di karma? Forse alcuni file non vengono caricati. – asoriano

0

1. Soluzione

nel test istanziare il controller genitore con un nuovo ambito:

mainScope = $rootScope.$new(); 
$controller('ParentController', {$scope: mainScope}); 

e nel controller figlio, creare un'istanza di un nuovo ambito utilizzando l'ambito precedentemente istanziato:

childScope = mainScope.$new(); 
$controller('ChildController', {$scope: childScope}); 

Esempio dal AngularJS documentation:

describe('state', function() { 

    var mainScope, childScope, grandChildScope; 

    beforeEach(module('myApp')); 

    beforeEach(inject(function($rootScope, $controller) { 
     mainScope = $rootScope.$new(); 
     $controller('MainController', {$scope: mainScope}); 
     childScope = mainScope.$new(); 
     $controller('ChildController', {$scope: childScope}); 
     grandChildScope = childScope.$new(); 
     $controller('GrandChildController', {$scope: grandChildScope}); 
    })); 

    it('should work', function() { 
     grandChildScope.searchText = "test"; 
     grandChildScope.submit(); 
    }); 
}); 

2. Soluzione

Child struttura del regolatore:

function ChildController() { 
    var vm = this; 

    vm.searchText = ''; 

    vm.submit = function() { 
    var data = {}; 
    data['srch'] = vm.searchText; 
    vm.parentCtrl.submitTextSearch(data); 
    }; 
} 

module.exports = ChildController; 

componente figlio:

var template = require('./child.html'); 
var controller = require('./child.controller'); 

    var childComponent = { 
     bindings: { 
     searchText: 'test' 
     }, 
     template: template, 
     controller: controller, 
     controllerAs: 'vm' 
    }; 

module.exports = childComponent; 

var ChildController = $componentController('childComponent', null, {...}); 
ChildController.$onInit(); 
expect(ChildController.searchText).to.equal('test'); 
expect(ChildController.submit()).to.equal('*expected result value should come here*'); 

refrences:

AngularJS documentation - Testing Controllers

AngularJS documentation - $componentController

Unit Testing Angular Components with $componentController

2

usando il codice seguente lo otterrà inizializzato e controllare il lavoro del gelsomino unit test Plunker

var ctrP = $componentController('parentComp'); 
var ctrl = $componentController('childComp', {}, { 
    parentCtrl: ctrP 
}); 

E il vostro banco di prova dovrebbe essere come illustrato di seguito:

'use strict'; 

describe('component: heroDetail', function() { 
    var $componentController, $compile, $rootScope; 

    beforeEach(module('plunker')); 
    beforeEach(inject(function(_$componentController_) { 
    $componentController = _$componentController_; 
    })); 

    it('should expose a `hero` object', function() { 
    var ctrP = $componentController('parentComp'); 
    console.log(ctrP); 
    var ctrl = $componentController('childComp', {}, { 
     parentCtrl: ctrP 
    }); 
    console.log(ctrl); 
    ctrl.submit('some data'); 
    expect(ctrl.parentCtrl.searchText).toEqual('some data'); 

    }); 
});