web-dev-qa-db-fra.com

Comment tester ComponentDidUpdate ()?

Ceci est un exemple d'implémentation:

export class Person extends Component {
  componentDidMount() {
    const { onLoadProfile, onLoadPolicy, person } = this.props
    onLoadProfile(person.profile.uri)
    onLoadPolicy(person.policy.uri)
  }

  componentDidUpdate(prevProps) {
    const { onLoadProfile, onLoadPolicy, person } = this.props
    const prevPerson = prevProps.person.uri
    const curPerson = person.uri

    // If person has changed, update Person component
    if (prevPerson !== curPerson) {
      onLoadProfile(person.profile.uri)
      onLoadPolicy(person.policy.uri)
    }
  }
}

Sur componentDidMount(), j'ai réussi à le tester comme ceci:

describe('<Person />', () => {
  let props
  let mountedPerson
  const mockLoadProfile = jest.fn()
  const mockLoadPolicy = jest.fn()

  const person = () => {
    if (!mountedPerson) {
      mountedPerson = mount(<Person {...props} />)
    } 
    return mountedPerson
  }

  beforeEach(() => {
    props = {
      onLoadProfile = mockLoadProfile,
      onLoadPolicy = mockLoadPolicy
    }
    mountedPerson = undefined
  })

  afterEach(() => {
    mockLoadProfile.mockClear()
    mockLoadPolicy.mockClear()
  })

  describe('componentDidMount', () => {
    it('loads profile', () => {
      person().instance().componentDidMount()
      expect(mockLoadProfile).toBeCalled()
    })

    it('loads policy', () => {
      person().instance().componentDidMount()
      expect(mockLoadPolicy).toBeCalled()
    })
  })
})

Sur componentDidUpdate(), il faudrait que le composant tente de tenter render() deux fois afin de vérifier s'il se met à jour quand il le devrait et inversement, mais je ne pouvais pas trouver le moyen approprié. pour le faire.

Quelle est la bonne approche pour tester une méthode componentDidUpdate() dans React?

PS .: J'utilise plaisanterie, enzyme et React 15.

15

J'utilise une approche différente mais vous pouvez copier l'idée. Vous devez faire un changement dans les accessoires, j'ai utilisé la fonction setProps ():

describe('componentDidUpdate', () => {
    it('loads profile', () => { 
        const wrapper = shallow(<Person  {...props} />) as any;
        wrapper.setProps({ person: { uri: "something_different" } });
        expect(wrapper.instance().props.onLoadProfile).toBeCalled();
    })
})

Je peux voir que le rose dans la page des tests de couverture est disparu dans le composantDidUpdate après l'exécution du test

26
Bonomi

La réponse acceptée est le moyen le plus simple de tester le cas ci-dessus, mais vous pouvez également envisager une solution en extrayant la logique componentDidUpdate du composant, comme suit:

// Component definition
export class Person extends Component {
  componentDidUpdate(prevProps) {
    this.props.handleComponentDidUpdate(prevProps, this.currentProps)
  }
  // Rest of component
}

// Component functions/handlers testing
describe('Person component props', () => {
  describe('handleComponentDidUpdate', () => {
    it('loads profile & policy if person changes', () => {
      const onLoadPolicy = jest.fn()
      const onLoadProfile = jest.fn()
      const prevProps = {
        person: { uri: 'some-person-uri-old' },
        policy: { uri: 'some-policy-uri' },
        profile: { uri: 'some-profile-uri' },
        onLoadPolicy,
        onLoadProfile
      }
      const props = {
        person: { uri: 'some-person-uri-new' }, // person uri changes
        policy: { uri: 'some-policy-uri' },
        profile: { uri: 'some-profile-uri' },
        onLoadPolicy,
        onLoadProfile
      }

      handleComponentDidUpdate(prevProps, props)

      expect(onLoadPolicy).toHaveBeenCalled()
      expect(onLoadProfile).toHaveBeenCalled()
    })
  })
})

De cette façon, le composant peut être aussi bête que possible. La logique de l'application peut être extraite dans des fonctions/gestionnaires plus faciles à tester. De cette façon, vous pouvez concentrer vos tests davantage sur la fonction (ce qui est plus facile à tester) et moins sur le composant (ce qui est plus difficile à tester).

En ce qui concerne l'utilisation du composant Person, vous fournissez simplement les accessoires requis, y compris handleComponentDidUpdate.

Si vous devez toujours tester le composant, vous pouvez effectuer le test simple suivant (notez que dans ce test, contrairement au test des fonctions/gestionnaires ci-dessus, la logique de l'application (personne, profil, stratégie, etc.) ne nous intéresse pas:

// Component testing
describe('<Person/>', () => {
  it('should call handleComponentDidUpdate on prop change', () => {
    const handleComponentDidUpdate = jest.fn()
    const prevProps = {
      someProp: 'some-prop-prev',
      handleComponentDidUpdate
    }
    const newprops = {
      someProp: 'some-prop-new',
      handleComponentDidUpdate
    }

    const wrapper = shallow(<Person { ...prevProps } />)
    wrapper.setProps(newprops)

    expect(handleComponentDidUpdate).toHaveBeenCalledWith(prevProps, newProps)
  })
})
1
Imran Ariffin