Is it possible to create a mock of an object obj such that Jasmine test like
expect(fakeB instanceof B).toBe(true);
passes?
In other words, I have a class A with a method convertToB which argument must be an instance of a class B:
function A(){
this.convertToB = function(elem){
if (!(elem instanceof B)){ throw an error}
...
...
}
}
I would like to cover with test that piece of code by creating a mock object that when being asked whether it is an instance of B would respond true.
For the moment I am forced to write tests kind of
- it('throws an error if the argument is a string')
- it('throws an error if the argument is an array')
- ...
which is a bit annoying. I expect a command like
var fakeB = jasmine.createFake('B')
so that the first line of code in this question would pass.
Is it possible to create a mock of an object obj such that Jasmine test like
expect(fakeB instanceof B).toBe(true);
passes?
In other words, I have a class A with a method convertToB which argument must be an instance of a class B:
function A(){
this.convertToB = function(elem){
if (!(elem instanceof B)){ throw an error}
...
...
}
}
I would like to cover with test that piece of code by creating a mock object that when being asked whether it is an instance of B would respond true.
For the moment I am forced to write tests kind of
- it('throws an error if the argument is a string')
- it('throws an error if the argument is an array')
- ...
which is a bit annoying. I expect a command like
var fakeB = jasmine.createFake('B')
so that the first line of code in this question would pass.
Share Improve this question asked Mar 26, 2014 at 7:55 AndrewAndrew 2,1685 gold badges23 silver badges35 bronze badges2 Answers
Reset to default 9I have dozens of places in my code exactly as yours. spyOn method of Jasmine 2.0 will do the job. Same with Jasmine 1.0 but I don't remember if the method is called/used exactly the same way. To the example:
var realB = new B();
// change realB instance into a spy and mock its method 'foo' behaviour to always return 'bar'
// it will still respond "true" to "realB instanceof B"
spyOn(realB, 'foo').and.returnValue('bar')
var realC = new C();
// C.baz is expecting instance of B to be passed as first argument
var result = C.baz(realB)
// assuming C.baz return realB.foo() concatenated with '123'
expect(result).toEqual('bar123');
Jasmine documentation has extensive list of examples of spies: http://jasmine.github.io/2.0/introduction.html
My implementation is as follows:
function proxyConstructor(obj) {
obj = obj || {};
for (var key in obj) {
this[key] = obj[key];
}
this.prop = 'runtime prop';
this.instanceMethod(1);
}
var TestClass = jasmine.createSpy(`TestClass.constructor`).and.callFake(proxyConstructor);
TestClass.prototype.instanceMethod = jasmine.createSpy(`TestClass#instanceMethod`);
TestClass.staticMethod = jasmine.createSpy(`TestClass.staticMethod`);
var ins = new TestClass();
expect(ins).toBe(jasmine.any(TestClass)) // success
expect(ins.prop).toBe('runtime prop'); // success
expect(ins.instanceMethod.toHaveBeenCalledWith(1)) // success