1

I understand what's going on in: Using Jasmine to spy on a function without an object and why it doesn't work in TypeScript. I also see this TypeScript answer: https://stackoverflow.com/a/43532075/2548010.

Unfortunately this only solves the case for imported spied on functions. I am testing a function that takes in a function, and I am trying to see that the passed in function is called with the correct parameters.

import { chowDown } from './file.ts';

interface Taco {
  filling: string;
  hasCheese: boolean;
  isCrispy: boolean;
}

describe('chowdown', () => {
  const eatTaco = (taco: Taco) => {};
  const expectedTaco = {filling: 'ground beef', hasCheese: false, isCrispy: true};

  it('eats the taco', () => {
    chowdown(eatTaco);
    expect(eatTaco).toHaveBeenCalledWith(expectedTaco);
  });
});

What I would like to do is something like

spyOn(eatTaco);
//or
spyOn(window, 'eatTaco');

None of the proposed solutions that I have found online actually work for this infrequent spy event. Does anyone have any ideas as to how to actually spy on eatTaco properly?

Thanks

Big Money
  • 9,139
  • 6
  • 26
  • 37

2 Answers2

1

Replace the eatTaco function with the following spy:

const eatTaco = jasmine.createSpy<(taco: Taco) => void>();

This TypeScript generics keeps you type safe.

HolgerJeromin
  • 2,201
  • 20
  • 21
0

Okay, I figured it out.

The declaration of eatTaco had to change from this:

  const eatTaco = (taco: Taco) => {};

to this:

  const eatTaco = jasmine.createSpy();

This still works with TypeScript and Jasmine is smart enough to properly handle toHaveBeenCalledWith(...) without the typings. You do lose a bit of type safety here, but as long as you have the type declared in the actual code - your test doesn't technically need it.

Big Money
  • 9,139
  • 6
  • 26
  • 37