Вопрос или проблема
У меня есть проект, который вычисляет расстояние между 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
.
Причины возможного сбоя теста
-
Неверная установка текущих нот: Вы устанавливаете текущие ноты для объекта
jamBuddy
с помощьюjamBuddy.setCurrentNotes(["F", "A#"])
. Убедитесь, что методcalculateDistance
действительно возвращает правильные значения для этих нот (например, расстояние между нотой F и нотой A#). -
Метод
checkAnswer
: Проверьте, как реализован методcheckAnswer
. Убедитесь, что он правильно проверяет переданный ответ на правильность и соответствует ли ответans
, который вы получите от методаcalculateDistance
. - Состояние
resultElement
: Убедитесь, чтоcheckCorrectAnswer
вызывается именно так, как вы ожидаете в вашем тесте, и что он действительно обновляет содержимоеresultElement
в соответствии с логикой, описанной в коде.
Как исправить тест
-
Проверьте ответы:
Убедитесь, что методcalculateDistance
возвращает именно те значения, которые вы ожидаете. В вашем коде вы ожидаете ответans
, который должен соответствовать расстоянию между нотами F и A#, а не ноте C, как в вашем изначальном примере.Измените
jamBuddy.setCurrentNotes(["F", "A#"]);
и уточните, какое расстояние вы действительно получаете. Для F и A# расстояние должно быть 4 полутонов по часовой стрелке и 8 против часовой стрелки (если считать по стандартной круговой таблице). -
Тестирование логики ответа:
it("должен отображать успешное сообщение, когда ответ правильный, после нажатия кнопки проверки", () => { jamBuddy.setCurrentNotes(["F", "A#"]); const [ans, ans1] = jamBuddy.calculateDistance(); // Обновляем значение инпута на правильный ответ answerInputElement.value = ans; checkCorrectAnswer(); // Вызывает функцию проверки // Проверяем, что результат соответствует ожидаемому expect(resultElement.textContent).toBe(successMsgObj.correctAnswerMsg(ans)); // предполагаемое успешное сообщение });
- Обратите внимание на синхронность:
Убедитесь, что все действия происходят в ожидаемом порядке. Если ваш код выполняет какие-либо асинхронные операции, такие как обработка событий, убедитесь, что вы обновляете результаты, как только операция завершена.
Дополнительные рекомендации
- Проверьте отладочную информацию, вывода в консоль, чтобы убедиться, что все шаги и значения соответствуют тому, что вы ожидаете на каждом этапе.
- Используйте
beforeEach
для подготовки состояния перед каждым тестом, чтобы избежать побочных эффектов от предыдущих тестов.
Надеюсь, эта информация поможет вам решить проблему и успешно пройти тесты вашего класса JamBuddy. Если вы столкнётесь с дополнительными трудностями, не стесняйтесь задавать вопросы!