Reputation: 65
(I'm using Karma to run Jasmine unit tests.)
My unit test breaks at compile time, even before I have a chance to employ an assertion. The break happens due to an undefined scope variable which the directive's controller logic relies on:
TypeError: Cannot read property 'setValid' of undefined
In the this error, there is an object called "labelCalls" which should have this "setValid" function. (Names are arbitrary, of course.)
Test below:
describe("A suite for testing field_label.js directive", function() {
var element, scope;
var formsMock;
beforeEach(
angular.mock.module('portalApp', function ($provide) {
$provide.value('TextManip');
formsMock = {};
$provide.factory('Forms', function() {
formsMock.useShorterFieldWidths = function () {
return true;
}
return formsMock;
});
})
);
beforeEach(inject(function($rootScope,$compile){
scope = $rootScope.$new();
scope.labelCalls = {};
element = angular.element('<field-label></field-label>');
element = $compile(element)(scope);
scope.$digest();
}));
it('should...',function(){
});
});
SO, my question is, how do I go about mocking values for these scope variables so that my directive can compile before assertions are run?
Here is the full directive:
'use strict';
portalApp.directive("fieldLabel", function () {
return {
restrict: "E",
scope: {formId: '@', fieldDef: '=', isFieldDefEditable: '@', isInvalid: '=', labelCalls: '='},
template: '<span style="margin-left:0px;">' +
'<label class="app-form-detail-field tips {{isInvalid ? \' app-form-detail-field-invalid\' : \'\'}}" title="{{tooltip}}">{{labelText}}<sup class="app-form-required-asterisk" ng-show="isRequired">*</sup></label>' +
'<img class="app-form-detail-img-btn" ng-show="{{editableFieldDefs && !isReadOnly}}" src="framework/images/delete_field.png" ng-click="deleteFieldIcon_Clicked()">' +
'<img class="app-form-detail-img-btn" ng-show="{{editableFieldDefs && !isReadOnly}}" src="framework/images/edit_field.png" ng-click="editFieldIcon_Clicked()">' +
'</span>',
replace: true,
controller: function ($scope, TextManip, Forms, FieldComponent) {
var fieldDef = $scope.fieldDef;
var useShorterFieldWidths = Forms.useShorterFieldWidths($scope.formId);
$scope.editFieldIcon_Clicked = function () {
Forms.showEditFieldDialog($scope.formId, fieldDef.field_name);
};
$scope.deleteFieldIcon_Clicked = function () {
Forms.deleteField($scope.formId, fieldDef.field_name);
};
$scope.labelCalls.setValid = function (isValid) {
$scope.isInvalid = !isValid;
};
$scope.labelCalls.setNewFieldDef = function (fieldDef) {
loadScopeBindings(fieldDef);
};
var loadScopeBindings = function (def) {
$scope.fieldDef = def;
fieldDef = def;
$scope.editableFieldDefs = ($scope.isFieldDefEditable === 'true');
$scope.isRequired = (fieldDef.required === 'Y');
$scope.isReadOnly = (fieldDef.read_only === 'Y');
var display_name = fieldDef.display_name;
var abbrev = TextManip.abbreviate(display_name, $scope.editableFieldDefs, $scope.isRequired, useShorterFieldWidths), tooltip = '';
if (abbrev !== display_name) {
tooltip = display_name;
display_name = abbrev;
}
$scope.labelText = display_name;
$scope.tooltip = tooltip;
};
loadScopeBindings(fieldDef);
}
};
});
Upvotes: 0
Views: 727
Reputation: 6725
can you change your declaration to
controller: function ($scope:any, TextManip, Forms, FieldComponent)
check out this question: karma TypeError "Cannot read property 'subscribe' of undefined"
Upvotes: 0