Тестирование оператора IF относительно состояния с помощью Enzyme

#reactjs #jestjs #enzyme

#reactjs #jestjs #enzyme

Вопрос:

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

Это находится в разделе IF. Ниже приведен код, который реализует редактирование:

 onEditNote = event => {
  const {
    target: { value: id }
  } = event;
  const obj = {
    title: this.state.title,
    body: this.state.body
  };

  // clear the errors while submitting

  this.setState({ titleError: "", bodyError: "" });

  if (obj.title === "") {
    this.setState({ titleError: "Title empty, please add title" });
  } else if (obj.body === "") {
    this.setState({ bodyError: "Body empty, please add body" });
  } else if (obj.title.length > 20) {
    this.setState({ titleError: "Title is too long." });
  } else {
    this.setState(state => {
      const list = state.notesArray.map(item => {
        if (item.id === id) {
          // eslint-disable-next-line no-param-reassign
          item.title = obj.title;
          // eslint-disable-next-line no-param-reassign
          item.body = obj.body;
        }
        return item;
      });

      localStorage.setItem("items", JSON.stringify(list));

      // eslint-disable-next-line no-undef
      $("#editModal").modal("close");
      this.onSuccessToast("Noted edited successfully.");
      return {
        list,
        title: "",
        body: ""
      };
    });
  }
};
  

Это строки в приведенном выше коде, которые не охвачены тестом, который я реализовал:

 if (item.id === id) {
  // eslint-disable-next-line no-param-reassign
  item.title = obj.title;
  // eslint-disable-next-line no-param-reassign
  item.body = obj.body;
}
  

И ниже приведен мой тест, который я внедряю, который не охватывает оператор IF, но я вижу, что я его рассмотрел:

 it("should edit a Note.", () => {
  wrapper = shallow(<App />);
  $.fn.modal = jest.fn();
  wrapper.instance().onEditNote({ target: { value: "0" } });

  wrapper.instance().setState({
    title: "huxy 12",
    body: "hey huxy this is not great.",
    notesArray: [{ title: "hey", body: "its good", id: "0" }]
  });

  wrapper.instance().setState(state => {
    state.notesArray.map(item => {
      if (item.id === "0") {
        // eslint-disable-next-line no-param-reassign
        item.title = state.title;
        // eslint-disable-next-line no-param-reassign
        item.body = state.body;
      }
      return item;
    });
  });
});
  

Чего мне не хватает в моем тесте?

РЕДАКТИРОВАТЬ Это мой отредактированный тест с помощью Jest Matchers, не работает.

 it('should edit a Note.', () => {
    wrapper = shallow(<App />);
    $.fn.modal = jest.fn();
    wrapper.instance().onEditNote({ target: { value: '0' } });

    wrapper.instance().setState({
      title: 'huxy 12',
      body: 'hey huxy this is not great.',
      notesArray: [{ title: 'hey', body: 'its good', id: '0' }],
    });

    wrapper.instance().setState((state) => {
      state.notesArray.map((item) => {
        if (item.id === '0') {
          // eslint-disable-next-line no-param-reassign
          item.title = state.title;
          expect(item.title).toBe(state.title);
          expect(item.title).not.toBeNull();
          // eslint-disable-next-line no-param-reassign
          item.body = state.body;
        }
        return item;
      });
    });

    wrapper.instance().onEditNote({ target: { value: 0 } });
  });
  

Это полное состояние :

 constructor(props) {
    super(props, props, props);
    this.state = {
      notesArray: [],
      id: '',
      title: '',
      body: '',
      search: '',
      titleDisplay: '',
      bodyDisplay: '',
      titleError: '',
      bodyError: '',
    };
    this.onHandleSubmit = this.onHandleSubmit.bind(this);
    this.onHandleChange = this.onHandleChange.bind(this);
  }
  

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

1. Какова цель этого теста? Он не содержит утверждений. Оно не охватывает ничего, не только cover if .

2. Спасибо @estus, я отредактировал свой вопрос с помощью jest matchers , но все еще эта область не охвачена. Пожалуйста, направьте меня.

Ответ №1:

Утверждения не должны помещаться внутри setState обратного вызова. setState предполагается, что он вызывается в оболочке Enzyme, а не в экземпляре. Ветви следует тестировать одну за другой, в зависимости от состояния ветви.

Это должно быть что-то вроде:

 wrapper = shallow(<App />);
// mock $(...).modal and localStorage.setItem
wrapper.setState({ title: '' });
wrapper.instance().onEditNote({ target: { value: '0' } });
expect(wrapper.state.titleError).toEqual({ title: '', titleError: ... );

wrapper = shallow(<App />);
// mock $(...).modal and localStorage.setItem
wrapper.setState({ title: '' });
wrapper.instance().onEditNote({ target: { value: '0' } });
expect(wrapper.state.titleError).toEqual({ body '', bodyError: ... );

// etc.
  

Обычно не следует издеваться над глобальными значениями путем присвоения, jest.fn() поскольку это может помешать их очистке, $(...).modal является jest.spy предпочтительным способом издевательства.

localStorage.setItem также необходимо высмеять.

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

1. Привет, спасибо за ответ, но я имел дело с notesArray[] состоянием. Проверьте в разделе РЕДАКТИРОВАНИЯ моего вопроса, я включил состояние.

2. Вы основывались на titleError и bodyError , но значения, которые я менял, находятся в notesArray. Итак, этот список содержит объекты title , id и body . Поэтому, когда он заполнен, это может быть примерно так : [{id:'0',title:"helllo","body:"am good"}] .

3. но значения, которые я менял, находятся в notesArray — нет, это не так, проверьте свой код еще раз. notesArray изменяется только в else . Я начал с самого начала, тестируя по одному условию за раз. Вы можете добавить отсутствующие ключи состояния в toEqual или использовать toMatchObject для assertb только ключи, которые изменены в onEditNote.

Ответ №2:

 I enhanced the following code  to test for 
const regex = /[^a-zA-Z0-9.s-] /;
  

принимать символы через запятую и — и пробел

 stringGenerator = (length) => {
  let result = '';
  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?:"}{} ,~amp;^$.\||$3#@%amp;()';
  const charactersLength = characters.length;
  for (let i = 0; i < length; i  = 1) {
    result  = characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return resu<
};
  

regex.test(stringGenerator(7))