3

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:

  1. Test this function with all id(here 1 and 2);
  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:

  1. Is there any ways to achieve the goal of the function testGetSchoolAdministrationById() without changing the function getCompanyById(id, callback)?(Cause this has a quite big influence to other Codes.)

  2. 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 of getCompanyById(id, callback) without using callbacks?

  3. 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.

2
  • Nest the callbacks, so that the second query will execute when the first one finishes. Commented Dec 5, 2021 at 3:11
  • …and once you have learned how this works with callbacks, learn about promises and use them instead. Commented Dec 5, 2021 at 3:14

2 Answers 2

1

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));
       }
    }
  );
  
}

Sign up to request clarification or add additional context in comments.

5 Comments

You wouldn't nest them inside the if statements though. It should still do the log (with value of false) if neither of the conditions are met.
Why not? Because if first of them is not pass, then it already not passed
Ah i get your point, updated my answer to log when if conditions are not met
Thanks for your Answer, it really helps me. It's really easier to understand this way. As @Bergi said, Is Promise a better way to deal with those? And what should I do, after I get my Answers? Click the "Answer your Question" button? Thanks again.
Absolutely, I also prefer to use promise, especially combined with async/await , why did I use callbacks? because your original code is based on callbacks, so I think it would be easier for you to understand. To accept answer you can click on check mark of the answer you'd like to accept
1

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));
  });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.