Acosta
Acosta

Reputation: 1055

Jasminejs - Test Callback

Nested function (change) to be tested

this.options.edit = (e: any) => {
    let type: any = this.getTrasactionTypeText(e.container);

    if (type !== undefined) {
        let transaction: any = this.getTrasactionType(e.container);

        transaction.change(() => {
            console.log('testing callback');                
        });
    }
};

Jasmine Test

it('should call back the nested function', async(() => {

    class callback {
        change = function() { };

    }

    let call = new callback();

    spyOn(component, 'getTrasactionTypeText').and.returnValue('CLOSEREASON');
    spyOn(component, 'getTrasactionType').and.returnValue(call);        

    let object: any = jasmine.createSpyObj('object', ['container', 'model']);
    object.model = { isMurex: true, isBloomberg: true, isFidessa: true, isMartini: true };

    component.options.edit(object);

    call.change();//This is not calling the nested function
}));

Upvotes: 1

Views: 958

Answers (1)

Seth Flowers
Seth Flowers

Reputation: 9190

call.change();//This is not calling the nested function

There's no reason it should. You are just calling a function there. I think that you think that you are firing an event, which is being handled by your code under test. That's not the right way to think about it.

Your code under test is just executing a function, and passing in an arrow function as an argument. One way to test would just be to check that your function is called. For instance, something like this (untested):

it('should call back the nested function', async(() => {    
  var callback = jasmine.createSpyObj('callback', ['change']);

  spyOn(component, 'getTrasactionTypeText').and.returnValue('CLOSEREASON');
  spyOn(component, 'getTrasactionType').and.returnValue(callback);        

  let object: any = jasmine.createSpyObj('object', ['container', 'model']);
  object.model = { isMurex: true, isBloomberg: true, isFidessa: true, isMartini: true };

  component.options.edit(object);

  expect(callback.change.calls.count()).toBe(1);
}));

Extending this further, you can check that the argument passed into the call is a function, which you can then execute yourself in your test, and assert against. For instance:

it('should pass a function into transaction.change()', async(() => {    
  var callback = jasmine.createSpyObj('callback', ['change']);

  spyOn(component, 'getTrasactionTypeText').and.returnValue('CLOSEREASON');
  spyOn(component, 'getTrasactionType').and.returnValue(callback);        

  let object: any = jasmine.createSpyObj('object', ['container', 'model']);
  object.model = { isMurex: true, isBloomberg: true, isFidessa: true, isMartini: true };

  component.options.edit(object);

  // Validate that the transaction.change() function was called once.
  expect(callback.change.calls.count()).toBe(1);

  // Validate that the function was given a single argument.
  var args = callback.change.calls.first().args;
  expect(args.length).toBe(1);

  // Validate that the single argument is itself another function.
  var actualFunc = args[0];
  expect(typeof actualFunc).toBe('function');

  // Execute the other function, and validate that it does xyz.
  actualFunc();
  // expect(...).toBe(...);
}));

Upvotes: 1

Related Questions