Юнит-тестирование с использованием JSDOM

Вопрос или проблема

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

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

Я столкнулся с проблемой, когда один тест постоянно не проходит, и я не понимаю, почему это происходит.

Для контекста, вот как работает класс:
Класс JamBuddy управляет музыкальными нотами, позволяя пользователям устанавливать текущие ноты, проверять их и вычислять расстояния между двумя нотами как по часовой, так и против часовой стрелки.

let buddy = new JamBuddy();
buddy.setCurrentNotes(["D#", "C"]);
console.log(buddy.calculateDistance()); // Вывод: [10, 2] (расстояния по часовой и против часовой стрелки между D# и C)

Вот что у меня есть на данный момент:

У меня есть функция, которая обновляет интерфейс с соответствующим сообщением об ошибке или успехе в зависимости от того, правильно ли пользователь ответил. Она работает как надо.

function checkCorrectAnswer() {
  const answer = parseInt(answerInputElement.value, 10);

  resultElement.textContent = "";

  if (answer.toString().includes(".")) {
    resultElement.textContent = errorMsgObj.answerFloat;
    clearDisplay();
  } else if (answer < 0) {
    resultElement.textContent = errorMsgObj.answerPositive;
    clearDisplay();
  } else if (answer > 12) {
    resultElement.textContent = errorMsgObj.invalidNumberRange;
    clearDisplay();
  } else {
    const isCorrectAnswer = jamBuddy.checkAnswer(answer);

    if (isCorrectAnswer) {
      resultElement.textContent = successMsgObj.correctAnswerMsg(answer);
      answerInputElement.disabled = true;
      checkAnswerBtn.disabled = true;
      streakCounterHandler();
      streakDisplay.innerHTML = `Текущая серия: ${streakCounter}`;
    } else {
      resultElement.textContent = errorMsgObj.incorrectAnswer;
      answerInputElement.disabled = false;
      checkAnswerBtn.disabled = false;
      clearDisplay();
    }
  }
}

Вот мой модульный тест:

it("должен отображать сообщение об успехе, когда ответ правильный, когда вы нажимаете кнопку проверки ответа", () => {
    jamBuddy.setCurrentNotes(["F", "A#"]);

    const [ans, ans1] = jamBuddy.calculateDistance();

    // Тестируем первый возможный ответ
    answerInput.value = ans;
    checkAnswerBtn.click();
    clock.tick(1000);

    expect(resultElement.textContent).toBe(successMsgObj.correctAnswerMsg(ans)); //"Правильный ответ!"

Тест не проходит, ожидая, что resultElement.textContent будет содержать “Неправильный ответ”.

Где я ошибся?

Я пытался переписать функцию, используя оператор switch, но безрезультатно.

Как мне заставить тест пройти?

Ответ или решение

Для решения вашей проблемы с юнит-тестированием класса JamBuddy, давайте сначала рассмотрим возможные причины, почему тест не проходит. У вас есть функция checkCorrectAnswer, которая проверяет, правильный ли ответ, и в зависимости от этого обновляет текстовый контент элемента resultElement.

Причины возможного сбоя теста

  1. Неверная установка текущих нот: Вы устанавливаете текущие ноты для объекта jamBuddy с помощью jamBuddy.setCurrentNotes(["F", "A#"]). Убедитесь, что метод calculateDistance действительно возвращает правильные значения для этих нот (например, расстояние между нотой F и нотой A#).

  2. Метод checkAnswer: Проверьте, как реализован метод checkAnswer. Убедитесь, что он правильно проверяет переданный ответ на правильность и соответствует ли ответ ans, который вы получите от метода calculateDistance.

  3. Состояние resultElement: Убедитесь, что checkCorrectAnswer вызывается именно так, как вы ожидаете в вашем тесте, и что он действительно обновляет содержимое resultElement в соответствии с логикой, описанной в коде.

Как исправить тест

  1. Проверьте ответы:
    Убедитесь, что метод calculateDistance возвращает именно те значения, которые вы ожидаете. В вашем коде вы ожидаете ответ ans, который должен соответствовать расстоянию между нотами F и A#, а не ноте C, как в вашем изначальном примере.

    Измените jamBuddy.setCurrentNotes(["F", "A#"]); и уточните, какое расстояние вы действительно получаете. Для F и A# расстояние должно быть 4 полутонов по часовой стрелке и 8 против часовой стрелки (если считать по стандартной круговой таблице).

  2. Тестирование логики ответа:

    it("должен отображать успешное сообщение, когда ответ правильный, после нажатия кнопки проверки", () => {
        jamBuddy.setCurrentNotes(["F", "A#"]);
    
        const [ans, ans1] = jamBuddy.calculateDistance();
    
        // Обновляем значение инпута на правильный ответ
        answerInputElement.value = ans;
        checkCorrectAnswer();  // Вызывает функцию проверки
    
        // Проверяем, что результат соответствует ожидаемому
        expect(resultElement.textContent).toBe(successMsgObj.correctAnswerMsg(ans)); // предполагаемое успешное сообщение
    });
  3. Обратите внимание на синхронность:
    Убедитесь, что все действия происходят в ожидаемом порядке. Если ваш код выполняет какие-либо асинхронные операции, такие как обработка событий, убедитесь, что вы обновляете результаты, как только операция завершена.

Дополнительные рекомендации

  • Проверьте отладочную информацию, вывода в консоль, чтобы убедиться, что все шаги и значения соответствуют тому, что вы ожидаете на каждом этапе.
  • Используйте beforeEach для подготовки состояния перед каждым тестом, чтобы избежать побочных эффектов от предыдущих тестов.

Надеюсь, эта информация поможет вам решить проблему и успешно пройти тесты вашего класса JamBuddy. Если вы столкнётесь с дополнительными трудностями, не стесняйтесь задавать вопросы!

Оцените материал
Добавить комментарий

Капча загружается...