Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jasmin: mock instance of a class

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

  1. it('throws an error if the argument is a string')
  2. it('throws an error if the argument is an array')
  3. ...

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.

like image 820
Andrew Avatar asked Mar 26 '14 07:03

Andrew


2 Answers

I 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

like image 167
Wojciech Szela Avatar answered Oct 20 '22 00:10

Wojciech Szela


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
like image 44
g13013 Avatar answered Oct 19 '22 23:10

g13013