是javascript的新手,我一直在尝试为他的代码编写测试,但是我却没有能力,我们应该使用笑话。 我已经研究了很长时间,没有找到解决方案。
document.getElementById("signup").addEventListener("submit", function(e) {
e.preventDefault();
data = {
username: document.getElementById("username").value,
email: document.getElementById("email").value,
password: document.getElementById("password").value,
confirm_password: document.getElementById("confirmPassword").value,
};
});
signUp = (data) => {
fetch("https://diaryapi-v2.herokuapp.com/mydiary/v1/auth/register", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(data => {
if (data.message === "Your account was created") {
let msg = data.message;
document.getElementById("white").innerHTML = msg;
window.location.href = "/signin";
} else {
let msg = Object.values(data);
console.log(msg)
document.getElementById("white").innerHTML = msg;
}
})
.catch(error => console.error("Error:", error));
}
答案 0 :(得分:1)
您的代码没有任何导出,因此您需要在测试运行时使用require()
。
它发出网络请求并设置窗口位置,因此您将需要使用Mocks Functions来验证它是否按预期工作,而无需实际发出网络请求和设置窗口位置。
它通过使用给then()
的回调来异步执行一些工作,因此您需要在测试中加以考虑。
Jest
使用jsdom
在单元测试中提供类似于浏览器的环境,您可以使用它来设置所有内容,然后再使用require()
运行代码。
我对以下注释中提到的您的代码做了一些小的修改:
code.js
document.getElementById("signup").addEventListener("submit", function (e) {
e.preventDefault();
// add 'const'
const data = {
username: document.getElementById("username").value,
email: document.getElementById("email").value,
password: document.getElementById("password").value,
confirm_password: document.getElementById("confirmPassword").value,
};
signUp(data); // call signUp with the data
});
// add 'const'
const signUp = (data) => {
fetch("https://diaryapi-v2.herokuapp.com/mydiary/v1/auth/register", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(data => {
if (data.message === "Your account was created") {
let msg = data.message;
document.getElementById("white").innerHTML = msg;
window.location.assign("/signin"); // change this to assign() so it can be mocked
} else {
let msg = Object.values(data);
console.log(msg)
document.getElementById("white").innerHTML = msg;
}
})
.catch(error => console.error("Error:", error));
}
这是上述代码的有效测试,可以用作参考:
code.test.js
describe('code', () => {
let fetchMock;
let assignMock;
beforeEach(() => {
// Jest uses jsdom as the default test environment which emulates
// a browser and provides a document object for the unit tests.
// Initialize the document body with the HTML needed for the tests
document.body.innerHTML += `
<form id="signup">
<input type="text" id="username" value="the username">
<input type="text" id="email" value="the email">
<input type="text" id="password" value="the password">
<input type="text" id="confirmPassword" value="the confirmPassword">
<input type="submit" id="submitbutton">
</form>
<div id="white"></div>
`;
// Create a mock for fetch and provide a mock implementation
// so the unit tests aren't actually making network requests
fetchMock = jest.spyOn(global, 'fetch');
fetchMock.mockImplementation(() => Promise.resolve({
json: () => Promise.resolve({ message: 'Your account was created' })
}));
// Create a mock for window.location.assign()
// so the unit tests aren't actually changing the window location
assignMock = jest.spyOn(window.location, 'assign');
assignMock.mockImplementation(() => {});
// With everything set up, require the code
require('./code');
});
afterEach(() => {
// After each test call mockRestore() to restore the original functions
fetchMock.mockRestore();
assignMock.mockRestore();
// resetModules() resets the module registry in Jest and ensures
// a fresh copy of './code' executes on require()
jest.resetModules();
});
it('should fetch data, change contents of #white, and change the page location on submit', async () => {
// Submit the form
document.getElementById('submitbutton').click();
// Check that fetch was called with the expected arguments
expect(fetchMock).toHaveBeenCalledTimes(1);
const fetchArgs = fetchMock.mock.calls[0];
expect(fetchArgs[0]).toBe('https://diaryapi-v2.herokuapp.com/mydiary/v1/auth/register');
expect(fetchArgs[1]).toEqual({
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
username: 'the username',
email: 'the email',
password: 'the password',
confirm_password: 'the confirmPassword',
})
});
// pause synchronous execution of the test for two event loop cycles
// so the callbacks queued by the then()'s within signUp have a chance to run
await Promise.resolve().then();
// Check that window.location.assign() was called with the expected arguments
expect(assignMock).toHaveBeenCalledTimes(1);
expect(assignMock.mock.calls[0][0]).toBe('/signin');
// Check that #white was updated
expect(document.getElementById('white').innerHTML).toBe('Your account was created');
});
});