Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

167
Views
Spy on functions without objects

Im testing a publish method on a pub sub class. I am creating a callback function within the beforeEach function and subscribing to the class. In the it method I am publishing the event and attempting to test that the callback was called which is basically how the class works. I have got the test working and it passes but the problem is I had to use a setTimeout to get this to work. I believe this is probably not the right way to do this.

describe('publish', () => {
  let testpublish;
  let callback;

  beforeEach(() => {
    callback = function(data) { return data + 10; }
    testpublish = {
      'id': 'testpublish1',
      'event': 'testpublish',
      'callback': callback
    };
    subject.subscribe(testpublish);
  });

  it('should call the subscription function', () => {
    subject.publish('testpublish', 9);
    setTimeout(() => {
      expect(callback).toEqual(19);
    });
  });
});

I initially wanted to spy on the callback just to see if it was called but the documentation for Jasmine says I must place my method in an object:

spyOn(obj, methodName) → {Spy}

Any advice on a better way to do this would be appreciated. Thanks.

PubSub Class if useful ??

@Injectable()
export class Pubsub {
  private events: any = {};

  public subscribe(config: any) {
    let event = config['event'];
    this.events[event] = this.events[event] || [];

    if (this.events[event].length < 1) {
      this.events[event].push(config);
    } else {
      for (let i = 0; i < this.events[event].length; i++) {
        if (this.events[event][i].id !== config.id) {
          this.events[event].push(config);
        }
      }
    }
  }

  public unsubscribe(obj: Object) {
    let event = obj['event'];
    let id = obj['id'];

    if (this.events[event]) {
      this.events[event] = this.events[event].filter((eventObj) => {
        return eventObj.id !== id;
      });
    }

    if (this.events[event].length === 0) {
      delete this.events[event];
    }
  }

  public publish(event: string, data: any) {
    if (this.events[event]) {
      this.events[event].forEach(function(obj) {
        obj.callback(data);
      });
    }
  }

  public getEvents() {
    return this.events;
  }
}
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Existing function cannot be spied, because a spy is a new function, and the reference to original function is already used in the place where it is being called.

Considering that callback function is defined in the test itself, not inside the application, it should be defined as a spy in the first place:

callback = jasmine.createSpy();

It doesn't even have to do something because its return value doesn't add value to the test.

And it is tested like

const arg = {};
subject.publish('testpublish', arg);

expect(callback.calls.count()).toBe(1);
expect(callback.calls.first().args[0]).toBe(arg);

publish is synchronous, as well the rest of the class. There's no need for setTimeout, and it is harmful here. When done parameter isn't specified for the test, it is considered synchronous, and setTimeout makes assertions ignored in this test.

This

  it('should pass', () => {
    setTimeout(() => {
      expect(1).toBe(2);
    });
  });

will always pass. And only if if the suite has no other tests, this will trigger SPEC HAS NO EXPECTATIONS warning.

over 4 years ago · Santiago Trujillo Report

0

jasmine.createSpy('spy') will do work.

 describe('publish', () => {
  let testpublish;
  let callback;
  let subject = new Pubsub();

  beforeEach(() => {

    callback = function (data) {
      return data + 10;
    }
    testpublish = {
      'id': 'testpublish1',
      'event': 'testpublish',
      'callback': jasmine.createSpy('spy')
    };
    subject.subscribe(testpublish);
  });

  it('should call the subscription function', () => {
    subject.publish('testpublish', 9);
    expect(testpublish.callback).toHaveBeenCalledWith(9);
  });
});
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!