P.G
P.G

Reputation: 81

How to test a function with a promise returned using jest?

Here is my function

const FS = require('fs');
const PARSER = new $RefParser;

const dereference = (filePath)=>{
  let parsedJSON = PARSER.dereference(filePath,{dereference: {circular: false}});

  return parsedJSON.then(result =>{
    const dereferencedJSON = JSON.stringify(result,null,2);
    FS.writeFileSync(filePath,dereferencedJSON);
  }).catch((error)=>{
      console.log(error.message);
  });
};

module.exports = {
  dereferenceSchema,
  PARSER
};

here is the test

const {dereferenceSchema,PARSER} = require('../../src/dereferenceService');

describe('derefrencing service test',() =>{
    it('Should throw ReferenceError if circular reference detected',  done => {
        beforeEach(()=>{
            PARSER.dereference = jest.fn();
       });
        dereferenceSchema(CIRCULAR_REF_FILE).then((data) => {
            console.log(data) // this gives me undefined
            done();
        })
        
    });
});

I also tried

describe('derefrencing service test',() =>{

    it('Should throw ReferenceError if circular reference detected',  async () => {
        expect.assertions(1);
        return dereferenceSchema(CIRCULAR_REF_FILE).catch((e)=>{
            expect(e).toEqual('ReferenceError');
        }
        );
    });
});
//This will have Error: Expected one assertion to be called but received zero assertion calls.

The implementation of test above is always pass no matter the what condition is, however, there still has the ReferenceError in console, which comes from my catch of derefrenceSchema function.

I am totally new to jest and I have tried different method, either using something working withdone() or jest.fn().

I would be really appreciate it if someone can help me here.

Upvotes: 3

Views: 1875

Answers (2)

P.G
P.G

Reputation: 81

Problem is solved by creating the other function used to catch errors, deleting .catch from the dereferenceSchema function.

const catchErrorFunc = (p) =>{
  dereferenceSchema(p).catch((error)=>{
    console.log(error.name);
    return error;
  });
};

Upvotes: 0

Code-Apprentice
Code-Apprentice

Reputation: 83527

There are a couple of issues to resolve here. First, return the promise from your test to allow the Jest framework to process it:

describe('derefrencing service test',() =>{
    it('Should throw ReferenceError if circular reference detected',  done => {
        beforeEach(()=>{
            PARSER.dereference = jest.fn();
        });

        // add "return" here:
        return dereferenceSchema(CIRCULAR_REF_FILE).then(() => {
            done();
        }).catch(e => {
            expect(e.name).toMatch('ReferenceError');
            done();
        });
        
    });
});

Second, you don't need both a .then() and a .catch() in your test. You should be testing only a single scenario that has a known outcome. For different inputs with different results, you should write separate tests for each scenario.

Third, there is evidence from your debugging that the promise returned by dereferenceSchema() is resolved, but it sounds like you expect it to throw an error. This means either dereferenceSchema() is incorrect or the test is incorrect. If dereferenceSchema() is incorrect, then you need to fix it accordingly. The test could be incorrect in at least two different ways:

  1. The setup is wrong and doesn't actually trigger the error you are testing for. This could be because the beforeEach() is in the incorrect place. It should be nested inside the describe(), but not in the it(). beforeEach() is run before each it() in a describe(). This is useful when you have multiple tests that require the same set up.

  2. The way you expect the result is wrong. You might just need to change your test to have an expect in a .then() clause instead of a .catch() clause.

Upvotes: 2

Related Questions