I'm currently researching my problem but I thought adding a question here may help as I'm new to AngularJS and even newer to Unit Testing.
I have the current directive that works, it users the $watch()
function to track a variable, if the variable is not present a default message is provided, for example "Deleted User Value" ...
angular.module('myModule')
.directive('displayName', function ($transform) {
return {
restrict: 'A',
scope: {
displayName: '='
},
link: function (scope, element) {
scope.$watch('displayName', function(value){
if(!value) {
element.html($transform('users.profile.deletedUser'));
} else {
element.html(value);
}
});
}
};
})
;
and I have the following unit test (please note that I have amended this on the advice of Maurice) :
beforeEach(module('myModule'));
beforeEach(inject(function($pile, $rootScope) {
$scope = $rootScope;
element = angular.element('<div class="name" display-name="name"></div>');
$pile(element)($scope);
}));
it('should display the deleted user name', inject(function() {
$scope.displayName = null;
element.scope().$apply();
console.log(element);
expect(element.html()).toBe('Deleted User Value');
}));
However I am getting the following issue: TypeError: Attempted to assign to readonly property
. and the console.log
is not being outputted, can anyone advise where I am going wrong? Sorry for my stupidity but I am trying to learn unit testing "on the job" and I am still very new to AngularJS
I'm currently researching my problem but I thought adding a question here may help as I'm new to AngularJS and even newer to Unit Testing.
I have the current directive that works, it users the $watch()
function to track a variable, if the variable is not present a default message is provided, for example "Deleted User Value" ...
angular.module('myModule')
.directive('displayName', function ($transform) {
return {
restrict: 'A',
scope: {
displayName: '='
},
link: function (scope, element) {
scope.$watch('displayName', function(value){
if(!value) {
element.html($transform('users.profile.deletedUser'));
} else {
element.html(value);
}
});
}
};
})
;
and I have the following unit test (please note that I have amended this on the advice of Maurice) :
beforeEach(module('myModule'));
beforeEach(inject(function($pile, $rootScope) {
$scope = $rootScope;
element = angular.element('<div class="name" display-name="name"></div>');
$pile(element)($scope);
}));
it('should display the deleted user name', inject(function() {
$scope.displayName = null;
element.scope().$apply();
console.log(element);
expect(element.html()).toBe('Deleted User Value');
}));
However I am getting the following issue: TypeError: Attempted to assign to readonly property
. and the console.log
is not being outputted, can anyone advise where I am going wrong? Sorry for my stupidity but I am trying to learn unit testing "on the job" and I am still very new to AngularJS
-
Is there a typo at the top?
$tranform
should be$transform
? – Michal Charemza Commented Dec 30, 2013 at 12:20
1 Answer
Reset to default 7There seem to be several things wrong with the code.
The directive has a dependency on $translate
which isn't used while a $transform
is used but not injected.
Secondly in your second test you are calling element.$scope().$apply();
. That should be element.scope().$apply();
instead.
Finally you are setting the displayName
property on the scope but binding to the name
property in the test code using <div class="name" display-name="name"></div>
.
I would write the tests something like this:
describe("The displayName directive", function () {
var $scope, element;
beforeEach(module('myModule'));
beforeEach(inject(function ($pile, $rootScope) {
$scope = $rootScope;
element = angular.element('<div class="name" display-name="name"></div>');
$pile(element)($scope);
}));
it('should display the deleted user name', function () {
element.scope().$apply();
expect(element.text()).toBe('users.profile.deletedUser');
});
it('should display the actual user name', function () {
$scope.name = "Maurice";
element.scope().$apply();
expect(element.text()).toBe('Maurice');
});
});