Search code examples
javascriptnode.jspromisees6-promise

NodeJS Promises returning Pending


Context: I am trying to set up testing using jest and supertest for a MongoDB application I am writing

The aim: Assign a value returned from the postArticleByAPI function to a constant id.

Issue: It's returning Promise { <pending> }

What I have tried:

  1. Promise.resolve(postArticleByAPI) results in the same issue.
  2. Chaining a .then((res) => {console.log(res}) results in undefined.

I think I fundamentally don't understand promises, or namely how to assign values they return outside of the promise. Is this possible? Anyone have any tips?

const articleData = {title: 'Hello123', doi: '123', journal: 'Facebook'};

/**
 * Posts an article through the API
 * @param {Object} article - the article objection containing dummy data
 * @return {string} request - the article id stored in the database
**/
async function postArticleByAPI(article) {
  await request(app)
      .post('/api/articles')
      .send(article)
      .expect(200)
      .then((response) => {
        expect(response.body.title).toBe(article.title);
        expect(response.body.doi).toBe(article.doi);
        expect(response.body.journal).toBe(article.journal);
        expect(response.body.id).toBeTruthy();
        return response.body.id;
      });
}


describe('Test POST through API', () => {
  test('It should response the POST method /api/articles', () => {
    const id = postArticleByAPI(articleData);
    console.log(id);
  });
});

Solution

  • Indeed postArticleByAPI returns a Promise and it's not resolved at the time you log it. You should write this instead:

    describe('Test POST through API', () => {
      test('It should response the POST method /api/articles', async () => {
        const id = await postArticleByAPI(articleData);
        console.log(id);
      });
    });
    

    Also don't forget to return the Promise from postArticleByAPI:

    function postArticleByAPI(article) {
      return request(app)
          .post('/api/articles')
          .send(article)
          .expect(200)
          .then((response) => {
            expect(response.body.title).toBe(article.title);
            expect(response.body.doi).toBe(article.doi);
            expect(response.body.journal).toBe(article.journal);
            expect(response.body.id).toBeTruthy();
            return response.body.id;
          });
    }
    

    If you want to use async and await, you should not use .then -

    async function postArticleByAPI(article) {
      const response =
        await request(app)
          .post('/api/articles')
          .send(article)
          .expect(200)
    
      expect(response.body.title).toBe(article.title);
      expect(response.body.doi).toBe(article.doi);
      expect(response.body.journal).toBe(article.journal);
      expect(response.body.id).toBeTruthy();
      return response.body.id;
    }