Ошибка: ожидаемая фиктивная функция была вызвана - энзим Jest onclick - PullRequest
0 голосов
/ 27 февраля 2019

Не удалось выполнить следующий тест ... Извините, что выложил много кода .... Я смог заставить работать некоторые другие события щелчка, но в данный момент я застрял с этим

Получение следующего сообщения:

"Ожидается (jest.fn ()). ToHaveBeenCalled ()

Ожидается, что была вызвана фиктивная функция."

вот событие click под методом Render

      className={!this.state.name || !this.state.label || this.state.valueStore === null ? `add-custom-field-button disabled` : `add-custom-field-button`}
          id="test-addclick"
          onClick={() => {this.onAddClick()}}
        >
          Create Field
        </button>

вот метод onAddClick:

onAddClick = () => {
let obj = this.props.selectedFormJSON;

this.addValueAttribute().then(()=>{
  obj.FORM_COLUMN.push(
    {
      Control: this.state.control,
      CreateBy: this.props.user.userId,
      Datatype: this.state.datatype,
      Form_UID: this.props.selectedFormJSON.Form_UID,
      Help: this.state.help,
      ValueStore: this.state.valueStore
    }
  )
  this.props.updateSelectedFormJSON(obj);
  if(!this.props.isNewForm && this.state.valueStore) {
    this.props.patchForm().then((res)=>{
    if(res.Forms[0] && (res.Forms[0].Code === '200' || res.Forms[0].Code===200)) {
      toast(<div>Attribute Added Successfully!</div>, {type: toast.TYPE.SUCCESS,position: toast.POSITION.TOP_LEFT})
    } else {
      toast(<div>Failed to Add Attribute!</div>, {type: toast.TYPE.ERROR,position: toast.POSITION.TOP_LEFT})
    }
  });
  } else if(this.state.valueStore) {
    this.props.postForm().then((res)=>{
      if(res.Forms[0] && (res.Forms[0].Code === '201' || res.Forms[0].Code===201)) {
        toast(<div>Attribute Added Successfully!</div>, {type: toast.TYPE.SUCCESS,position: toast.POSITION.TOP_LEFT})
      } else {
        toast(<div>Failed to Add Attribute!</div>, {type: toast.TYPE.ERROR,position: toast.POSITION.TOP_LEFT})
      }
    })
  }
  this.props.closeModal();
})
}

     addValueAttribute = () => {
return new Promise((resolve, reject) => {
  if(this.state.valueStore) {
    let {valueTables, valueDatatypes, service} = this.state;
    let body = {
      Name: this.state.name,
      TableName: this.props.selectedFormJSON.Entity,
      Datatype: this.state.datatype,
      ChangeType: 'I'
    }
    fetch(service.URL+'/VALUE_ATTRIBUTE', { headers: {
      'Content-Type': 'application/json',
      'Ocp-Apim-Subscription-Key': service.subscription_key,
    },
      method: 'POST',
      credentials: 'include',
      body: JSON.stringify(body),
    })
    .then((res) => {
      res.status === 201 && resolve();
    })
    .catch(() => {
      reject();
    })
  } else {
    //Not a value attr
    resolve()
  }
})

}

Вот как я пытаюсь проверитьэто: используя шутку / фермент.Я использовал ту же настройку для некоторых других событий щелчка, и она работала.Невозможно выяснить следующее:

it("should call onAddClick", async () => {  // use an async test method
baseProps. closeModal.mockClear();
baseProps. updateSelectedFormJSON.mockClear();

const instance = wrapper.instance();
const spy = jest.spyOn(instance, 'addValueAttribute');  // spy on addValueAttribute...
spy.mockImplementation(() => Promise.resolve())  // give any callbacks queued in PromiseJobs a chance to run
wrapper.find('#test-addclick').at(0).simulate('click');  // simulate click

expect(baseProps.updateSelectedFormJSON).toHaveBeenCalled();  // SUCCESS
expect(baseProps.closeModal).toHaveBeenCalled();  // SUCCESS
});

1 Ответ

0 голосов
/ 28 февраля 2019

addValueAttribute стоит дорого, поэтому вы захотите посмеяться над ним, чтобы решить немедленно.addValueAttribute является полем класса , поэтому вам нужно будет смоделировать его с помощью экземпляра компонента.

Когда вызывается onAddClick, он вызовет this.addValueAttribute, который будет смоделирован для немедленного возврата,Это приведет к добавлению обратного вызова Promise в then к очереди PromiseJobs .Задания в этой очереди запускаются после завершения текущего сообщения и до начала следующего сообщения .

Это означает, что обратный вызов, который вызывает this.props.updateSelectedFormJSON и this.props.closeModal, ставится в очередь в очереди PromiseJobs, когдаобработчик щелчков возвращается, и тест продолжается.

На этом этапе вам необходимо приостановить свой тест, чтобы дать возможность выполнить обратный вызов, поставленный в очередь в PromiseJobs.Самый простой способ сделать это состоит в том, чтобы сделать вашу тестовую функцию async и вызвать await Promise.resolve();, которая, по существу, поставит в очередь оставшуюся часть теста в конце очереди PromiseJobs и позволит вначале запускать любые задания, уже находящиеся в очереди.

Собрав все воедино, вот упрощенная версия вашего кода с рабочим тестом:

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

class Comp extends React.Component {
  onAddClick = () => {
    this.addValueAttribute().then(() => {
      this.props.updateSelectedFormJSON();
      this.props.closeModal();
    })
  }
  addValueAttribute = () => {
    return new Promise((resolve) => {
      setTimeout(resolve, 100000);  // does something computationally expensive
    });  
  }
  render() {
    return (<button onClick={this.onAddClick}>Create Field</button>);
  }
}

it("should call onAddClick", async () => {  // use an async test method
  const props = {
    updateSelectedFormJSON: jest.fn(),
    closeModal: jest.fn()
  }
  const wrapper = shallow(<Comp {...props} />);
  const instance = wrapper.instance();
  const spy = jest.spyOn(instance, 'addValueAttribute');  // spy on addValueAttribute...
  spy.mockResolvedValue();  // ...and mock it to immediately resolve
  wrapper
    .find('button')
    .at(0)
    .simulate('click');  // simulate click
  await Promise.resolve();  // give any callbacks queued in PromiseJobs a chance to run
  expect(props.updateSelectedFormJSON).toHaveBeenCalled();  // SUCCESS
  expect(props.closeModal).toHaveBeenCalled();  // SUCCESS
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...