Big Money
Big Money

Reputation: 10088

Using Jasmine to spy on a non-imported function without an object in TypeScript

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

Upvotes: 1

Views: 353

Answers (2)

HolgerJeromin
HolgerJeromin

Reputation: 2462

Replace the eatTaco function with the following spy:

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

This TypeScript generics keeps you type safe.

Upvotes: 1

Big Money
Big Money

Reputation: 10088

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.

Upvotes: 0

Related Questions