Jest Enzyme Как обновить дочерний реквизит

#reactjs #jestjs #enzyme

#reactjs #jestjs #энзим

Вопрос:

Мне нужно изменить реквизит дочернего компонента React, который получает родительскую функцию. После обновления функции оболочки она изменяется, но не влияет на дочерний компонент

 // Component
import React from 'react';

export default class Component extends React.Component {
  clickFunction() {
    console.log("Parent's Click fn");
  }
  render() {
    return (
      <div>
        <Button onClick={this.clickFunction} data-test-id="button" />
      </div>
    );
  }
}
  
 // Test

import React from 'react';
import {shallow} from 'enzyme';

const mockClickFunction = jest.fn(() => console.log('Mock Click fn'));

describe('Test Component', () => {
   it('Should mutate child prop', () => {
      const wrapper = shallow(<Component />);
      wrapper.find('[data-test-id="button"]').simulate('click') // Parent's Click fn

      console.log(wrapper.instance().clickFunction) // [Function: bound clickFunction]

      wrapper.instance().clickFunction = mockClickFunction;
      wrapper.update();

      console.log(wrapper.instance().clickFunction) // [Function: mockConstructor]

      wrapper.find('[data-test-id="button"]').simulate('click') // Parent's Click fn but should be Mock Click fn
   })
})
  

Как я могу изменить функцию onClick дочернего компонента?

Комментарии:

1. Что именно вы тестируете? Что он будет вызывать две отдельные функции при последующих щелчках? Возможно, было бы лучше протестировать эффекты щелчка (при условии, что они разные).

2. для компонента он загрузит изображение. но для теста я отправлю фиктивные данные. вот почему мне нужно издеваться над этой функцией

3. Я обнаружил, что после изменения родительского состояния реквизиты дочернего компонента будут обновлены. wrapper.setState({someState: ‘newstate’})

4. Попробуйте wrapper.instance().forceUpdate();

Ответ №1:

При рендеринге была использована ссылка на оригинал clickFunction . Вы не можете издеваться над ним, переопределяя его после того, как компонент уже обработан мелким способом.

Попробуйте шпионить Component.prototype.clickFunction перед вызовом shallow .

Например.

index.jsx :

 import React from 'react';

export default class Component extends React.Component {
  clickFunction() {
    console.log("Parent's Click fn");
  }
  render() {
    return (
      <div>
        <button onClick={this.clickFunction} data-test-id="button" />
      </div>
    );
  }
}
  

index.test.tsx :

 import { shallow } from 'enzyme';
import React from 'react';
import Component from '.';

describe('55611882', () => {
  it('should pass', () => {
    const mockClickFunction = jest
      .spyOn(Component.prototype, 'clickFunction')
      .mockImplementation(() => console.log('Mock Click fn'));

    const wrapper = shallow(<Component />);
    wrapper.find('[data-test-id="button"]').simulate('click');
    expect(mockClickFunction).toBeCalledTimes(1);
    mockClickFunction.mockRestore();
  });
});
  

результат теста:

  PASS  examples/55611882/index.test.jsx (13.099 s)
  55611882
    ✓ should pass (81 ms)

  console.log
    Mock Click fn

      at examples/55611882/index.test.jsx:9:41

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |      75 |      100 |      50 |      75 |                   
 index.jsx |      75 |      100 |      50 |      75 | 5                 
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        15.416 s