spyOn
's second parameter is the name of the property you need to spy on. When you call spyOn(window, myWindow('list'));
, your second parameter is the return value of myWindow('list')
which is undefined
=> throws error: undefined() method does not exist
In your code, simply doing this should work:
describe('#myView', function() {
beforeEach(function() {
fixture.load('myview.html');
});
it('sets window to list', function(){
spyOn(window, "myWindow");//spy the function
myView();//call your method that in turn should call your spy
expect(window.myWindow).toHaveBeenCalledWith('list');//verify
});
});
In software unit testing, there are concepts called stub and mock objects. These are dependencies of the method under test. spyOn
is to create your fake objects to test your methods.
You're accessing the global window
object directly, that's really a problem in unit testing. Although Javascript is a dynamically typed language, we're still able to mock your window
object (this is not possible with some statically-typed languages like c#). But to create a good unit-testable code, I recommend you should redesign your code to inject it from outside.
function myView(awindow){ //any dependency should be injected, this is an example to inject it via parameter
if($('.view').is('.list')){
awindow.myWindow('list');
}else{
awindow.myWindow('random');
}
$('.view').toggleClass('my-list');
}
Try this:
describe('#myView', function() {
beforeEach(function() {
fixture.load('myview.html');
});
it('sets window to list', function(){
var spy = {myWindow:function(list){}};
spyOn(spy, "myWindow"); //create a spy
myView(spy); //call your method that in turn should call your spy
expect(spy.myWindow).toHaveBeenCalledWith('list'); //verify
});
});
One more thing, jQuery code like this is not quite a good candidate for unit testing as it involves DOM manipulation in your code. If you have time, you should take a look at angularjs framework that separates your View (DOM) from your model (logic), uses dependency injection to make your code testable.