Jasmine: how to spy on inner object method call?

11,315

Solution 1

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();
  });
});

Solution 2

I don't think it's possible because inner object is not accesible from outside the parent object. It's all about the scope of your objects.

You could either expose your Child object in Person object by doing this:

var Person = function() {
    this.boy = new Child();
};

Person.prototype.pingChild = function(){
   this.boy.getAge();
}

And then:

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

Or delegate the initialization of the Child outside the Person object:

var Person = function(child) {
    this.boy = child;
};

Person.prototype.pingChild = function(){
   this.boy.getAge();
}

And then:

describe("Person", function() {
    it("calls the getAge() function", function() {
        var chi = new Child();
        var fakePerson = new Person(chi);
        spyOn(chi, "getAge");
        fakePerson.pingChild();
        expect(chi.getAge).toHaveBeenCalled();
    });
});
Share:
11,315
Victoria Agafonova
Author by

Victoria Agafonova

Updated on June 11, 2022

Comments

  • Victoria Agafonova
    Victoria Agafonova almost 2 years

    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?