Search code examples
javascriptunit-testingtestingbddjasmine

Jasmine: how to spy on inner object method call?


I have two prototypes I want to test:

var Person = function() {};

Person.prototype.pingChild = function(){
   var boy = new Child();
   boy.getAge();
}

var Child = function() {};

Child.prototype.getAge = function() {
    return 42;
};

What exactly I want to test: to check that getAge() method is called inside of the pingChild() method

That is Jasmine specs I try to use for this purpose:

describe("Person", function() {
    it("calls the getAge() function", function() {
        var fakePerson = new Person();
        var chi = new Child();
        spyOn(fakePerson, "getAge");
        fakePerson.pingChild();
        expect(chi.getAge).toHaveBeenCalled();
    });
});

describe("Person", function() {
    it("calls the getAge() function", function() {
        var fakePerson = new Person();
        spyOn(fakePerson, "getAge");
        fakePerson.pingChild();
        expect(fakePerson.getAge).toHaveBeenCalled();
    });
});

describe("Person", function() {
    it("calls the getAge() function", function() {
        var fakePerson = new Person();
        var chi = new Child();
        spyOn(chi, "getAge");
        fakePerson.pingChild();
        expect(chi.getAge).toHaveBeenCalled();
    });
});

but all of them shows just errors:

  • getAge() method does not exist
  • getAge() method does not exist
  • Expected spy getAge to have been called

So, is there any way to test such cases using Jasmine, and if yes - how can it be done?


Solution

  • You have yo spy on the prototype of Child object.

    describe("Person", function () {
      it("calls the getAge() function", function () {
        var spy = spyOn(Child.prototype, "getAge");
        var fakePerson = new Person();
        fakePerson.pingChild();
        expect(spy).toHaveBeenCalled();
      });
    });