Reputation: 19463
I have a directive that look like this:
angular.directive('myDirective', ['$window', function($window){
return function (scope, element) {
var w = angular.element($window);
var top = element.offset().top-w.scrollTop();
function adjustTop(){
var oldtop = scope.top;
var scrolltop = w.scrollTop();
var winHeight = w.height();
console.log("scrolltop:"+scrolltop);
console.log("winHeight :"+winHeight);
var newtop = top - scrolltop;
if(newtop>15){
scope.top = top - scrolltop;
}else{
scope.top = 15;
}
if(oldtop!=newtop){
scope.$apply();
}
}
w.bind('scroll', function () {
adjustTop();
});
adjustTop();
};
}]);
I want to do an unit test to detect its adjustment on the element top
position based on the window scrolling.
Here are my questions:
Update:
After taking Andrew's advice, this is my $window
mock:
var mock$window;
beforeEach(module('my-app', function ($provide) {
mock$window = {
scrollTop : 200,
height: 960
};
$provide.value('$window', mock$window);
})
);
When I run the test, I am able to get the result of w.scrollTop()
, but w.height()
returns the error
Cannot use 'in' operator to search for 'height' in undefined.
Without mocking, I don't get any JavaScript error in the test, but the w.scrollTop()
value is 0
and the w.height()
is the browser window height of the PhantomJS browser running the test.
So, How can I get a w.height()
mock works in unit tests?
Here is the sample of code to better illustrate the problem: http://jsfiddle.net/w4h5q5hr/
Upvotes: 1
Views: 6184
Reputation: 39
Create spys for things you want to mock like:
spyOn($window, 'scrollTop').and.returnValue(100);
If you're mocking jQuery calls you can use $.fn like so:
spyOn($.fn, 'scrollTop').and.returnValue(100);
Upvotes: 2
Reputation: 28757
Your best bet is to provide a mock $window
object. You can provide a mock $window
in a beforeEach
clause. The idea here is that you are unit testing and you can just assume that $window
works as designed.
Something like this will work:
var mock$window, scrollTop = 100;
beforeEach(module('my-app', function ($provide) {
mock$window = {
scrollTop : function() { return scrollTop; }
bind : function(eventName, cb) { ... }
};
$provide.value('$window', mock$window);
})
);
Then, in your tests, you can:
adjustTop
works appropriately with different scrollTop values.This is sufficient for unit testing your code, but if you want to truly see that this code works in an actual application setting, you may want to try something like protractor.
Upvotes: 2