Here is my Problem:
I need to write a Test in Node.js for a function, which select the data from database. It returns the value by using a callback function.(Code is down below.)
getCompanyById(id, callback) {
let company = null;
this.db.query("SELECT * FROM Company where id=?", id)
.on('result', function (data) {
company = data;
})
.on('end', function () {
callback(company);
});
}
What I want to do in the Test function is:
- Test this function with all id(here 1 and 2);
- If all the Tests passed, console.log("Test for getCompanyById() passed").
And here is the original version of my test Code.
function testGetSchoolAdministrationById() {
var pass1,pass2;
databaseConnection.getSchoolAdministrationById(1, function (schoolAdministration) {
if(schoolAdministration.first_name == "Harald" &&
schoolAdministration.last_name == "Schmidt" &&
schoolAdministration.id_schoolAdmin == 1)
pass1=true;
}
);
databaseConnection.getSchoolAdministrationById(2, function (schoolAdministration) {
if(schoolAdministration.first_name == "Madeline" &&
schoolAdministration.last_name == "Müller" &&
schoolAdministration.id_schoolAdmin == 2)
pass2=true;
}
);
console.log("Test for getCompanyById() passed: " (pass1 && pass2));
}
But it returns "undefined". After I searched on Internet, I realized that Node.js is Asynchrony and it won't work this way. console.log("..")
have already finished, while the callback have not yet. Also I have seen Answers, like use another Callback function to deal with the value. But in my case I have 2 Callbacks and no idea how to do it.
So here is my question:
Is there any ways to achieve the goal of the function
testGetSchoolAdministrationById()
without changing the functiongetCompanyById(id, callback)
?(Cause this has a quite big influence to other Codes.)If the 1. question is not possible, is there any ways to achieve the goal, while the function
getCompanyById(id, callback)
can be changed? In other word, is there any better ways to achieve the same goal ofgetCompanyById(id, callback)
without using callbacks?Or maybe a Test Framework will help this? I'm not using any Test Framework, cause I haven't tried and I' not really familiar to those.
This is my first Project about Node.js, so I am not very confident about any concept I mentioned above. So any suggestions and answers are welcomed. And since this is also my first question on Stack overflow, any suggestions about the questions/title/structure are also welcomed. Hope that, I described this clearly. I really want to figure this out.
CodePudding user response:
You mean to log the string once the test done?
Well you have to use nested callbacks to make it in your desired order.
So after first id in db check is done, proceed for next id check inside of the first id callback.
function testGetSchoolAdministrationById() {
var pass1,pass2;
databaseConnection.getSchoolAdministrationById(1, function (schoolAdministration) {
if(schoolAdministration.first_name == "Harald" &&
schoolAdministration.last_name == "Schmidt" &&
schoolAdministration.id_schoolAdmin == 1){
pass1=true;
databaseConnection.getSchoolAdministrationById(2, function (schoolAdministration) {
if(schoolAdministration.first_name == "Madeline" &&
schoolAdministration.last_name == "Müller" &&
schoolAdministration.id_schoolAdmin == 2){
pass2=true;
console.log("Test for getCompanyById() passed: " (pass1 && pass2));
}
else {
console.log("Test for getCompanyById() passed: " (pass1 && pass2));
}
}
);
}
else {
console.log("Test for getCompanyById() passed: " (pass1 && pass2));
}
}
);
}
CodePudding user response:
You can achieve this easily by using Promises.
One method would be making use of async/await keywords.
async function testGetSchoolAdministrationById() {
try {
const pass1 = await new Promise((resolve) => {
databaseConnection.getSchoolAdministrationById(1, function(schoolAdministration) {
resolve(schoolAdministration.first_name == "Harald" &&
schoolAdministration.last_name == "Schmidt" &&
schoolAdministration.id_schoolAdmin == 1);
});
}),
pass2 = await new Promise((resolve) => {
databaseConnection.getSchoolAdministrationById(2, function(schoolAdministration) {
resolve(schoolAdministration.first_name == "Madeline" &&
schoolAdministration.last_name == "Müller" &&
schoolAdministration.id_schoolAdmin == 2);
})
});
console.log("Test for getCompanyById() passed: " (pass1 && pass2));
} catch (e) {
console.error(e);
}
}
Or with a Promise.all(arrPromises).then(results)
call
function testGetSchoolAdministrationById() {
Promise.all([new Promise((resolve) => {
databaseConnection.getSchoolAdministrationById(1, (schoolAdministration) => {
resolve(schoolAdministration.first_name == "Harald" &&
schoolAdministration.last_name == "Schmidt" &&
schoolAdministration.id_schoolAdmin == 1);
});
}), new Promise((resolve) => {
databaseConnection.getSchoolAdministrationById(2, (schoolAdministration) => {
resolve(schoolAdministration.first_name == "Madeline" &&
schoolAdministration.last_name == "Müller" &&
schoolAdministration.id_schoolAdmin == 2);
})
})]).then(([pass1, pass2]) => {
console.log("Test for getCompanyById() passed: " (pass1 && pass2));
});
}