i am attempting to create a new instance of two classes that i have already written in separate files. when i try to create new instances of them in the beforeEach() section of the test code, the tests return undefined for my newly created objects. however when i create them in each IT section the test run perfectly.
describe("placeStone", function() {
beforeEach(function() {
var go = new Display();
var logic = new Internals(go);
logic.tempBoard = [ array];
});
it("should place a black stone at 0,6", function() {
logic.placeStone(logic.black,0,6);
expect(logic.tempBoard[6][0]).toEqual("B");
});
this returns logic undefined.
describe("placeStone", function() {
it("should place a black stone at 0,6", function() {
var go = new Display();
var logic = new Internals(go);
logic.tempBoard = [ array];
logic.placeStone(logic.black,0,6);
expect(logic.tempBoard[6][0]).toEqual("B");
});
});
this seems to work the way i want. how can i get it to work in the beforeEach() section?
var logic should be defined in the scope of the describe function, then it exists both in the scope of the beforeEach function and the spec (the it function), e.g.
describe('suite', function () {
var myVar;
beforeEach(function(){
myVar = 10;
});
it('checks myVar', function () {
expect(myVar).toEqual(10);
});
});
Related
I am trying to use Jasmine to test the following function:
var Pdba = Class.create();
Pdba.prototype = {
getChangeGroup: function(userId) {
var query = 'active=true^u_change_group=true^u_organization=false^';
var exGroup = new CompanyGroup();
var groups = exGroup.getGroupsByQuery(userId, query); //want to spy/mock this call
if (groups.next()) {
return groups.sys_id.toString();
}
return '';
}
type: 'Pdba'
};
I want to SpyOn the getGroupsByQuery() call, so that it doesn't make the actual call. Below is a collection of various things I have been trying, mostly just to see if I can "spy" and see that it has been called, then work on overriding so that I can replace the call with my own data.
describe('my suite of getChangeGroup tests', function() {
var expPdba;
var validUserId = 'user1';
var expGrp;
var ggbqMoc
beforeEach(function() {
expPdba = new global.Pdba();
coGrp = new CompanyGroup();
spyOn(coGrp, 'getGroupsByQuery');
ggbqMoc = jasmine.createSpy('getGroupsByQuery');
});
it('should return \'\' for empty userId', function() {
coPdba.getChangeGroup('');
expect(coGrp.getGroupsByQuery).toHaveBeenCalled();
expect(ggbqMoc).toHaveBeenCalled();
});
});
Is this possible or do I need to change the function under test to take a 'CompanyGroup' as a parameter?
Thank you
I'm assuming you are using jasmine v3. The syntax for creating a spy is pretty weird now- you have to pass a string that refers to the name of the variable you want to create a spy for, and then you pass an array of function names that should be spied on.
Try this:
describe('my suite of getChangeGroup tests', function() {
var expPdba;
var validUserId = 'user1';
var expGrp;
var spy;
beforeEach(function() {
expPdba = new global.Pdba();
coGrp = new CompanyGroup();
spy = jasmine.createSpyObj('coGrp', ['getGroupsByQuery'])
});
it('should return \'\' for empty userId', function() {
coPdba.getChangeGroup('');
expect(coGrp.getGroupsByQuery).toHaveBeenCalled();
expect(spy).toHaveBeenCalled();
});
});
I'm try to learn this tech and somehow getting stuck at the opening.
Please tell me why this test isn't working. What obvious thing did I miss?
var myfunc = function() {
alert('hello');
}
test("should spy on myfunc", function() {
var mySpy = sinon.spy(myfunc);
myfunc();
sinon.assert.calledOnce(mySpy);
});
It's the scope of myfunc. This works:
var o = {
myfunc: function() {
alert('hello');
}
};
test("should spy on myfunc", function() {
var mySpy = sinon.spy(o, "myfunc");
o.myfunc();
sinon.assert.calledOnce(mySpy);
ok(true);
});
The reason your test is not working is because you're not invoking the spy, rather the original function.
And the reason #carbontax's example works is because in that case, o.myfunc is replaced by the spy automatically; so when you invoke o.myfunc, you're actually invoking the spy.
As Mrchief said, you are not invoking spy but calling myfunc();, you should invoke spy something like.
test("should spy on myfunc", function() {
var mySpy = sinon.spy(myfunc);
mySpy(); // <= should called instead of myfunc()
sinon.assert.calledOnce(mySpy);
});
I've got a underscore/backbone/require application and I would like to output all events that are triggered through backbone to the console (in other words: pass each event through console.log function). I've tried wrapping it with underscore and manually replacing the function. Neither this:
console.log(Backbone.Events.trigger);
var trigger = Backbone.Events.trigger;
Backbone.Events.trigger = function(name) {
console.log('Event', name, 'triggered.');
trigger.apply(this, arguments);
}
nor this:
Backbone.Events.trigger = _.wrap(Backbone.Events.trigger, function(func) {
console.log('EVENT:', Array.prototype.slice.call(arguments));
func(Array.prototype.slice.call(arguments));
});
console.log(Backbone.Events.trigger);
worked. I'd appreciate a javascript (not coffeescript) solution.
Your wrappings fail because Backbone mixes in Backbone.Events behavior on Backbone.Model, Backbone.Collection, etc. For example, Backbone.Model is defined as
var Model = Backbone.Model = function(attributes, options) {
...
};
_.extend(Model.prototype, Events, {
...
};
This means that when you redefine Backbone.Events.trigger, it is already too late.
But all is not lost! You won't be able to redefine all trigger methods in one go, but you can redefine them on class level:
Backbone.Model.prototype.trigger = function() {
console.log('Event', arguments);
Backbone.Events.trigger.apply(this, arguments);
}
and a demo http://jsfiddle.net/nikoshr/G2Qfn/
For a given class, you can override the trigger method:
var M = Backbone.Model.extend({
trigger: function() {
console.log('Event', arguments);
Backbone.Model.prototype.trigger.apply(this, arguments);
}
});
http://jsfiddle.net/nikoshr/G2Qfn/1/
or for a given instance
var M = Backbone.Model.extend({});
var m = new M();
m.trigger = function() {
console.log('Event', arguments);
M.prototype.trigger.apply(this, arguments);
}
http://jsfiddle.net/nikoshr/G2Qfn/2/
This is my bootstrap:
LanesBoard2010 = (function () {
var appRoot = this;
appRoot.deferredLoad = new Object(); //holding jqxhr states
appRoot.utils = {}; //namespace for helper classes
appRoot.models = {};
appRoot.data = (function () { } ()); //store data from webservices here
appRoot.app = (function () { } ()); //ViewModel
}();
After some initialisation i run my deferred app loader:
function appStart() {
appRoot.deferredLoad.app = $.getScript('../TaskBoardContent/Script/app/lanesboard.js');
$.when.apply($, appRoot.deferredLoad.app).then(function () {
if (window.console)
if (debug)
console.log('application lanesdashboard was loaded successfully\n');
}, function () {
if (window.console)
if (debug)
console.log('fatal error: unable to load application lanesdashboard\n');
});
};
Now i need to access appRoot, or more general, modify the properties of LanesBoard2010.
the following statement is from my lanesboard.js. It just fails after the first console.log, as i can see both variable names are unknown:
(function () {
if (window.console)
if (true) {
console.log('App has been initialised successfully');
console.log('Status of app access 1: ' + appRoot);
console.log('Status of app access 2: ' + LanesBoard2010);
}
}());
May sound stupid, but how can i safely access my variables? Is there any best practice? How would you do this?
What exactly is your question? How you can prevent to use an undefined variable?
You can either define it before any calls and initialise it to null (var appRoot = LanesBoard2010 = null)
or check the variable before you call console.log() (if (appRoot) console.log('Status of app access 1: ' + appRoot);).
I normally use the first suggestion.
I first set all my caches to null, create the autocompletes, then use $.ajax to load them and when loaded, update the autocomplete sources.
Here is my plugin
(function($){
$.fn.myPlugin = function(options){
var defaults = {
width: 800
};
var defaults = $.extend(defaults, options);
var self = this;
function init(obj){
/*Initialize object*/
self.myPlugin.doAnimation(600,400);
}
$.fn.myPlugin.doAnimation = function(lV, rV){
/*Doing some animation work*/
}
return this.each(function(options){
init(this);
});
}
})(jQuery);
I am trying like this
var t = $('#id1').myPlugin();
t.doAnimation(); //getting error here, t.doAnimation is not a function
You can't. You're not returning the plugin. You're returning the jQuery object with the matched element(s) (like you probably should). The testing function is private to the myPlugin function anyway.
To call a method against a jQuery object, you would need to extend jQuery like you did for your myPlugin(), as in:
function($){
$.fn.myPlugin = function(options) {
...
}
$.fn.testing = function(options) {
...
}
})(jQuery);
Of course this would be completely separate from the original plugin.
I don't know what your plugin does, but if you need to share some data between plugins on a per-element basis, you could probably use jQuery's .data() method.