Leonardo Raygoza
Leonardo Raygoza

Reputation: 479

Jest spy on component's property method

I'm trying to test if an event has been added in the init method called by componentDidMount, but that event is going to be added only if a component's attribute is set in "true" so I want to spy on the addEventHandler method and call the "toBeCalledWith('eventName')" so I have something like this:

export interface IMyComponentProps{
    flag?: boolean;
}

export class MyComponent extends Component<IMyComponentProps> {
    private myProperty: HTMLElement;

    public componentDidMount() {
        this.init();
    }

    private init() {
        if (this.props.flag) {
            this.myProperty.addEventListener("event", arg2, arg3);
        }
    }
}

Then I have my test looking like this:

test("Test 1", () => {
   const spyInit = jest.spyOn(MyComponent.prototype, "init");
   wrapper = mount(
      <MyComponent />
   );

   expect(spyInit).toBeCalled();
})

but the test above does not cover if the addEventListener is called or not so I'm trying different ways like following, without success:

const spyAddListener = jest.spyOn(MyComponent.prototype, "myProperty.addEventHandler"); 
const spyAddListener = jest.spyOn(MyComponent.instance().myProperty, "addEventHandler"); 
const spyAddListener = jest.spyOn(MyComponent.prototype.myProperty, "addEventHandler");

any suggestion?

Upvotes: 11

Views: 31321

Answers (2)

Victor Zakharov
Victor Zakharov

Reputation: 26424

Not exactly answering the question, but people who are migrating from jasmine to jest may find this useful.

jest.spyOn(component, 'propertyName', 'get').mockReturnValue(...);

This is an equivalent to jasmine's spyOnProperty:

jasmine.spyOnProperty(component, 'propertyName').and.returnValue(...);

Upvotes: 44

Lin Du
Lin Du

Reputation: 102297

You need to pass the flag props to the component. E.g.

index.ts:

import { Component } from 'react';

export interface IMyComponentProps {
  flag?: boolean;
}

export class MyComponent extends Component<IMyComponentProps> {
  private myProperty!: HTMLElement;

  public componentDidMount() {
    this.init();
  }
  public render() {
    return null;
  }

  private init() {
    if (this.props.flag) {
      this.myProperty.addEventListener('event', () => null, false);
    }
  }
}

index.test.tsx:

import { MyComponent } from './';
import { mount } from 'enzyme';
import React from 'react';

describe('60714899', () => {
  it('should add event listener', () => {
    const spyInit = jest.spyOn(MyComponent.prototype as any, 'init');
    const mMyProperty = { addEventListener: jest.fn() } as any;
    MyComponent.prototype['myProperty'] = mMyProperty;
    const wrapper = mount(<MyComponent flag={true} />);
    expect(spyInit).toBeCalled();
    expect(mMyProperty.addEventListener).toBeCalledWith('event', expect.any(Function), false);
  });

  it('should NOT add event listener', () => {
    const spyInit = jest.spyOn(MyComponent.prototype as any, 'init');
    const mMyProperty = { addEventListener: jest.fn() } as any;
    MyComponent.prototype['myProperty'] = mMyProperty;
    const wrapper = mount(<MyComponent flag={false} />);
    expect(spyInit).toBeCalled();
    expect(mMyProperty.addEventListener).not.toBeCalled();
  });
});

unit test results with 100% coverage:

 PASS  stackoverflow/60714899/index.test.tsx
  60714899
    ✓ should add event listener (42ms)
    ✓ should NOT add event listener (2ms)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |   92.31 |      100 |      80 |     100 |                   
 index.tsx |   92.31 |      100 |      80 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.77s, estimated 10s

source code: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60714899

Upvotes: 5

Related Questions