personalizadas - ¿Cómo probar el valor de resolución de la ruta de Angularjs en el componente?
formularios en angular 6 (2)
Estoy usando [email protected]
y [email protected]
algún recurso en el nivel de ruta para uno de mis componentes. El componente funciona como se esperaba pero mi prueba falla ahora.
Error
PhantomJS 2.1.1 (Linux 0.0.0) module ag.expense-claim ExpenseClaimController: should load data FAILED
TypeError: undefined is not an object (evaluating ''vm.attachedReceipts.results'') (line 16)
ExpenseClaimViewController@app/expenses/expense_claim.js:16:50
ExpenseClaimViewController@[native code]
instantiate@node_modules/angular/angular.js:4733:61
$controller@node_modules/angular/angular.js:10369:39
node_modules/angular-mocks/angular-mocks.js:2221:21
$componentController@node_modules/angular-mocks/angular-mocks.js:2264:25
test/expenseSpec.js:18:40
invoke@node_modules/angular/angular.js:4718:24
workFn@node_modules/angular-mocks/angular-mocks.js:3085:26
loaded@http://localhost:9876/context.js:151:17
inject@node_modules/angular-mocks/angular-mocks.js:3051:28
test/expenseSpec.js:14:26
test/expenseSpec.js:11:13
global code@test/expenseSpec.js:1:9
Error: No pending request to flush ! in node_modules/angular-mocks/angular-mocks.js (line 1799)
flush@node_modules/angular-mocks/angular-mocks.js:1799:76
test/expenseSpec.js:53:31
loaded@http://localhost:9876/context.js:151:17
PhantomJS 2.1.1 (Linux 0.0.0): Executed 43 of 43 (1 FAILED) (0.257 secs / 0.387 secs)
error Command failed with exit code 1.
Prueba
describe(''ExpenseClaimController:'', function () {
var $scope, ctrl, attachedReceipts;
beforeEach(inject(function ($rootScope, $componentController, $stateParams) {
var attachedReceipts = {results: [{}]};
$scope = $rootScope.$new();
$stateParams.expenseClaimId = 1;
ctrl = $componentController(''expenseClaim'', {
$scope: $scope,
attachedReceipts: attachedReceipts
});
}));
it(''should load data'', function () {
…
});
Componente
angular.module(''ag.expenses'')
.component(''expenseClaim'', {
templateUrl: ''…'',
controller: ExpenseClaimViewController,
controllerAs: ''vm'',
bindings: {
attachedReceipts: "<"
}
});
function ExpenseClaimViewController($stateParams, $uibModal, API, gettextCatalog, alert) {
var vm = this;
vm.attachedReceipts = vm.attachedReceipts.results;
…
}
Ruta
.state(''expense-claim'', {
url: ''/home_expense_report/:expenseClaimId'',
template: ''<expense-claim attached-receipts="$resolve.attachedReceipts"></expense-claim>'',
resolve: {
attachedReceipts: function (API, $stateParams) {
return API.TransportCostAttachment.query({expenseClaimId: $stateParams.expenseClaimId}).$promise;
}
}
})
Pregunta
Implemente mi solución en base a ¿Cómo puedo simular los valores de resolución de ui-router al probar la configuración de un estado? pero todavía no puede conseguirlo para las obras. ¿Qué me estoy perdiendo?
la resolución en el ángulo 1.5 no es DI como el angular 2, por lo que para 1.5 debe pasarlo como un enlace, algo como esto:
var bindings = { attachedReceipts: attachedReceipts };
ctrl = $componentController(''expenseClaim'', {
$scope: $scope
}, bindings);
Además de la respuesta de Ameer, me gustaría proporcionar algunos detalles más ya que luché mucho para encontrarlos, si tiene un componente y necesita probar el controlador directamente o si desea probar la plantilla, tiene dos maneras de crear el controlador que tienen enlaces (ya sea que provengan de una resolución desde el ui-router o no importa)
- Unidad de prueba del controlador de componentes:
Como dijo Ameer, debes pasarlo como un enlace :
beforeEach(inject(function(_$componentController_) {
$componentController = _$componentController_;
}));
it(''should expose a `hero` object'', function() {
// Here we are passing actual bindings to the component
var bindings = {hero: {name: ''Wolverine''}};
var ctrl = $componentController(''heroDetail'', null, bindings);
expect(ctrl.hero).toBeDefined();
expect(ctrl.hero.name).toBe(''Wolverine'');
});
Método $ onInit:
Si su controlador tiene el método $ onInit (), no se ejecutará automáticamente como espera, necesita llamar manualmente el método después de crear el controlador, aquí encontrará más detalles sobre este problema.
- Unidad de prueba de la plantilla del componente:
Cuando la unidad prueba la plantilla de un componente, aún necesita crear una instancia del controlador, así es como puede hacerlo:
beforeEach(inject(($injector) => {
$rootScope = $injector.get(''$rootScope'');
$compile = $injector.get(''$compile'');
scope = $rootScope.$new();
scope.attachedReceipts = {results: [{}]};;
template = $compile(''<expense-claim attached-receipts="attachedReceipts"></expense-claim>'')(scope);
scope.$apply();
});
it(''should test something'', () => {
//Example of something you could test
expect(template.find(''h3'').html()).to.eq(''this is our first content page'');
});
Con este segundo método, se llamará al método $ onInit (), por lo que no es necesario que lo llame de forma manual. Puede encontrar un tutorial completo sobre cómo probar una plantilla dentro de un componente aquí