Any way to take a look at the whole instance with Jasmine

I have a complex javascript class that has many functions, many of which will throw exceptions if they are called outside the production environment. I need to pass the mock instances of this class to the constructor of another class in my tests, however I do not want any of the functions of complex classes to actually be called. What I would like to do is to have a fake object that has all the functions and properties of a complex class, but for all functions just to be jasmine spies that do nothing.

Mostly I want to be able to do

var fakeComplexClass = createFakeObject(ComplexClass); var testInstanceOfSimpleClass = new SimpleClass( fakeComplexClass); 

And make sure that if testInstanceOfSimpleClass calls any of the fakeComplexClass functions, they will be spies and thus will not break my tests.

I could do something like

 var fakeComplexClass = { function1() {};, function2() {}; ... } 

but there are many functions, and I have several different complex classes that I need to test, so the simple way to basically track every single function in the class is what I need. \

Jasmine has createSpyObj, but requires you to pass an array of functions to it. I don't want to support this array in my tests if I manage to add or remove functions from a complex class, so I need something that can just spy on every function that is.

Thanks in advance.

+4
source share
2 answers

Take a look at SinonJS, it will let you stub the whole object:

var stub = sinon.stub(obj); Blocks all object methods.

0
source

I created a small lib library that works with jasmine-node.

using:

  var MyClass = function (param) { this.initialize(param); }; MyClass.prototype.initialize = function (param) { if (param != "expectedParam") throw new TypeError(); }; var mock1 = jasmine.createStub(MyClass, ["*"]); expect(mock1.constructor).toHaveBeenCalled(); expect(mock1.initialize).not.toHaveBeenCalled(); var mock2 = jasmine.createStub(MyClass, ["initialize"], ["expectedParam"]); expect(mock2.initialize).toHaveBeenCalled(); mock2.initialize.andCallThrough(); expect(mock2.initialize).toThrow(new TypeError()); 

Lib:

 jasmine.createStub = function (cls, methods, args) { if (!(cls instanceof Function)) throw new TypeError("Invalid class param."); var mockClass = function () { this.constructor.apply(this, args || []); }; mockClass.prototype = Object.create(cls.prototype); mockClass.prototype.constructor = cls; var wrap = function (method) { if (!mockClass.prototype[method] instanceof Function) throw new TypeError("Cannot mock " + method + " it not a function."); jasmine.getEnv().currentSpec.spyOn(mockClass.prototype, method); }; if (methods) { if (!(methods instanceof Array)) methods = [methods]; if (methods.length == 1 && methods[0] == "*") for (var property in mockClass.prototype) { if (mockClass.prototype[property] instanceof Function) wrap(property); } else for (var i = 0; i < methods.length; ++i) { var method = methods[i]; wrap(method); } } return new mockClass(); }; 

I think this line will not work with jasmine in the browser, but did not check it:

 jasmine.getEnv().currentSpec.spyOn(mockClass.prototype, method); 

Somehow my jasmine - node has no jasmine.spyOn method ...

+1
source

Source: https://habr.com/ru/post/1392785/


All Articles