Jest Как проверить ошибку при отправке данных на сервер из формы?

Рассмотрим следующий код:

class Dashboard extends Component {
  state = {
    fileName: "",
    group: "",
    country: "",
    error: ""
  };
  onFormSubmit = async e => {
    e.preventDefault();
    const { group, country } = e.target;
    try {
      await axios.post("/api/dashboard", {
        name: group.value,
        country: country.value,
        image: this.state.fileName
      });
    } catch (error) {
      console.info(error.response.data.message);
      this.setState({ error: error.response.data.message });
    }
  };

  render() {
    return (
      <div>
        <form onSubmit = {this.onFormSubmit}>
          <input
            type = "text"
            onChange = {this.onGroupChange}
            name = "group"
            placeholder = "Group Name"
            value = {this.state.group}
          />
          {this.state.error}
          <input
            type = "text"
            onChange = {this.onCountryChange}
            name = "country"
            placeholder = "Country"
            value = {this.state.country}
          />
          <ImageUpload
            fileName = {this.state.fileName}
            onFileNameChange = {this.onFileNameChange}
          />
          <button type = "submit">Add Group</button>
        </form>
      </div>
    );
  }
}

Я пытаюсь проверить, что состояние error установлено на соответствующее значение при сбое почтового запроса. Вот тест на данный момент:

  it("should set error state when dashboard api returns error", async () => {
    const errorMsg = "Group already exist";
    moxios.stubRequest("/api/dashboard", {
      status: 400,
      response: {
        message: errorMsg
      }
    });
    const event = {
      preventDefault: () => {},
      target: {
        group: "",
        country: ""
      }
    };
    const wrapper = shallow(<Dashboard />);
    await wrapper.find("form").simulate("submit", event);
    console.info(wrapper.state("error").value);
    expect(wrapper.state("error")).toBe(errorMsg);
  });

Вы пробовали wrapper.update() до выражения ожидания?

curlyBraces 27.10.2018 04:58

@curlyBraces Ага

Unity Hour 27.10.2018 04:58
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
2
931
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку метод onformSubmit - это async, вы можете использовать несколько подходов:

1 Дождитесь асинхронного метода напрямую:

it(
  'should set error state when dashboard api returns error',
  async () => {
    const wrapper = shallow(<Dashboard />);
    await wrapper.instance().onFormSubmit(event);
    expect(wrapper.state('error')).toBe(errorMsg);
  }
);

и отдельно проверьте, что метод onFormSubmit был вызван при событии submit

2 Использовать тайм-аут с возвратом Promise:

it(
  'should set error state when dashboard api returns error',
  () => {
    const wrapper = shallow(<Dashboard />);
    wrapper.find("form").simulate("submit", event);
    return new Promise(resolve => setTimeout(resolve, 1)).then(() => {
      expect(wrapper.state('error')).toBe(errorMsg);
    });
  },
  1000
);

3 await поставить галочку перед проверкой:

function tick() {
  return new Promise(resolve => {
    setTimeout(resolve, 1);
  });
}

...

it('should set error state when dashboard api returns error', async () => {
  const wrapper = shallow(<Dashboard />);
  wrapper.find('form').simulate('submit', event);
  await tick();
  expect(wrapper.state('error')).toBe(errorMsg);
});

4 Использовать обратный вызов done:

it('should set error state when dashboard api returns error', done => {
  const wrapper = shallow(<Dashboard />);
  wrapper.find('form').simulate('submit', event);
  setImmediate(() => {
    expect(wrapper.state('error')).toBe(errorMsg);
    done();
  });
});

Тест проходит, что бы ни случилось. Ни один из них не работает. Можете ли вы предоставить полный код?

Unity Hour 27.10.2018 06:44

Ваш первый подход полностью похож на мой

Unity Hour 27.10.2018 06:45

@UnityHour Что вы имеете в виду под passing? Разве это не должно пройти? Вот код тестового файла: pastebin.com/y7gRk8mk. Обратите внимание, что я убрал константы из метода it, просто для того, чтобы показать разницу подходов.

extempl 27.10.2018 07:03

Мой первый подход - ожидание асинхронного метода, а не результата вызова события.

extempl 27.10.2018 07:03

@UnityHour добавил два других подхода, а также обновил pastebin. Все они хорошо работают.

extempl 27.10.2018 07:27

Другие вопросы по теме