#javascript #unit-testing #jestjs
#javascript #модульное тестирование #jestjs
Вопрос:
В моем тесте я создал функцию с именем postData, которая возвращает фиктивные данные json через обещание. Я использую это для тестирования функции urlValidation, которая использует функцию postData для добавления данных json в DOM. Я также добавил DOM внутрь теста.
testUrl.spec.js
import { urlValidation } from '../client/js/urlValidation';
import { printData } from '../client/js/checkStatement';
test('Testing url Validation', () => {
document.body.innerHTML = `
<body>
<header>
<div class="logo">
Logo
</div>
<div class="title">
Title
</div>
<div class="menu">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Contact</a></li>
<li> <a href="#">Body</a></li>
<li><a href="#">Footer</a></li>
</ul>
</div>
</header>
<main>
<section class="form-section">
<form class="blog-entry-text" onsubmit="return Client.checkStatement(event)">
<input id="text-input" type="text" name="input" value="" placeholder="Enter Text">
<button onclick="return Client.checkInput(event)">SubmitInput</button>
</form>
<form class="blog-entry-url">
<input id="text-url" type="text" name="input" value="" placeholder="Enter Text">
<button onclick="return Client.checkUrl(event)">SubmitURL</button>
</form>
<section>
<section class="form-results">
<strong>Form Results:</strong>
<div id="results"></div>
</section>
</main>
<footer>
<p>This is a footer</p>
</footer>
</body>`
const postData = (input1, input2) => { return Promise.resolve({
text: 'Hello',
language: 'en',
categories: [
{
label: 'religious festival or holiday - easter',
code: '12014002',
confidence: 0.54
}
]
})
};
urlValidation('What is going on', postData);
expect(document.querySelector('#results').innerHTML).toEqual(`<p>Text Data: Testing Input</p><p>Label: religious festival or holiday - easter</p>`)
});
Функция urlValidation принимает функцию в качестве параметра, а затем из данных json, которые возвращаются из promise, добавляет значения в DOM.
urlValidations.js
const urlValidation = (inputText, callback) => {
const inputData = {input: inputText};
callback("http://localhost:8080/classify-url", inputData).then(data =>{
console.log(data);
printData(inputData, data);
});
};
Функция печати данных управляет DOM и добавляет данные на веб-страницу.
printData.js
function printData(dataObj, data) {
console.log(`Data: ${data} DataObj: ${dataObj}`);
const results = document.getElementById('results');
const languageSystem = document.createDocumentFragment();
const p = document.createElement('p');
p.innerHTML = `Text Data: ${dataObj.input}`;
languageSystem.appendChild(p);
if (data.categories.length == 0) {
const label = document.createElement('p');
label.innerHTML = `Label: None`;
languageSystem.appendChild(label);
} else {
data.categories.forEach(element => {
console.log(element);
const label = document.createElement('p');
label.innerHTML = `Label: ${element.label}`;
languageSystem.appendChild(label);
console.log(`Label: ${languageSystem.innerHTML}`);
});
}
console.log(data);
console.log(`Results: ${languageSystem.innerHTML}`);
results.appendChild(languageSystem);
}
Когда я запускаю тест, я получаю этот результат обратно:
Expected: "<p>Text Data: Testing Input</p><p>Label: religious festival or holiday - easter</p>"
Received: ""
68 |
69 | urlValidation('What is going on', postData);
> 70 | expect(document.querySelector('#results').innerHTML).toEqual(`<p>Text Data: Testing Input</p><p>Label: religious festival or holiday - easter</p>`)
| ^
71 | });
at Object.toEqual (src/__tests__/testUrl.spec.js:70:58)
Test Suites: 1 failed, 1 passed, 2 total
Tests: 1 failed, 1 passed, 2 total
Snapshots: 0 total
Time: 4.036 s
Ran all test suites.
npm ERR! Test failed. See above for more details.
Что странно, поскольку у меня был тест, в котором я смог добавить данные json непосредственно в функцию PrintData, и этот тест работает нормально.
Я также сделал кучу консольных.войдите в журнал, чтобы проверить, правильно ли передавались данные json в функцию PrintData, и, похоже, что это был результат.
console.log
Label: religious festival or holiday - easter
at log (src/client/js/checkStatement.js:45:21)
at Array.forEach (<anonymous>)
console.log
{
text: 'Hello',
language: 'en',
categories: [
{
label: 'religious festival or holiday - easter',
code: '12014002',
confidence: 0.54
}
]
}
at log (src/client/js/checkStatement.js:49:13)
Я почти уверен, что делаю что-то не так, но я просто не могу понять, что.
Ответ №1:
Возникает состояние гонки, вызванное тем, что есть обещания, которые не связаны цепочкой.
urlValidation
должен вернуть обещание:
return callback("http://localhost:8080/classify-url", inputData).then(...);
Затем это можно ожидать в тесте или любом другом месте, где требуется его последовательное выполнение:
await urlValidation('What is going on', postData);
expect(...)
Комментарии:
1. Спасибо, это было именно то, что мне было нужно. Ты потрясающий!
Ответ №2:
Заслуга принадлежит Эстусу Фласку, поскольку именно он помог мне понять, что это было условие гонки.
Итак, что я должен был сделать, измените тест на асинхронный тест.
test('Testing url Validation', async () => {
....
и добавьте await для ожидания результатов перед запуском ожидаемого теста
await urlValidation('What is going on', postData);
expect(document.querySelector('#results').innerHTML).toEqual(`<p>Text Data: What is going on</p><p>Label: religious festival or holiday - easter</p>`)
еще раз отдаю должное Estus Flask, спасибо за вашу помощь!