1

I've inherited a JS application (Node). JS is not my strongest suit, and definitely not Promises. I've been tasked to bring the code up to modern standards, i.e. using classes and async/await. I am trying to be a good developer and create unit tests as well. Calls to the db have been pulled out into a separate persistor class, which the intent is to mock. However, the mock I created does not seem to work. It appears that the await is not waiting, so likely something wrong with the way I am mocking. The test fails with expected {} to deeply equal { Object (status, method, ...) }.

Here is my mock persistor.

const mockPersistor = {
    getModels: function getModels() {
        RootLogger.debug('mockPersistor.getModels()');
        return {
            Category: 'Category',
            Attribute: 'Attribute',
            Option: 'Option'
        };
    },
    setModels: function setModels() {
        RootLogger.debug('mockPersistor.setModels()');
    },
    findXref: function findXref(model, conditions) {
        RootLogger.debug(`mockPersistor.findXref(${model}, ${JSON.stringify(conditions)})`);

        return new Promise((resolve, reject) => {
            return {
                status: 'success',
                method: `findXref`,
                model: `${model}`,
                conditions: `${conditions}`
            };
        });
    }
};

The method under test is:

async getMagentoCategoryByNetSuiteId(netSuiteId, netSuiteRecordName) {
    this.log.debug(`SystemXrefCache.getMagentoCategoryByNetSuiteId(${netSuiteId}, ${netSuiteRecordName})`);

    const result = await this.findXref(
        this.models.Category, 
        { 
            netSuiteId: JSON.parse(netSuiteId), 
            netSuiteRecordName: netSuiteRecordName 
        }
    ); 

    return result;
}

The findXref method only redirects to the new persistor class method I've created (for greater refactoring purposes) of the same name:

async findXref(model, conditions) {
    this.log.debug(`SystemXrefCache.findXref(${JSON.stringify(model)}, ${JSON.stringify(conditions)})`);
    return await this.persistor.findXref(model, conditions);
}

I have tried several variations of creating a promise in the mock, all to no avail. I have async/await all down the line - unless I am just missing the obvious, so that should not be the problem.

So, perhaps the problem is in the test itself? I have tried a few things here as well, but this is my latest:

it('getMagentoCategoryByNetSuiteId returns successfully', function() {
        RootLogger.debug(`=== starting test getMagentoCategoryByNetSuiteId returns successfully ===`);
        const givenNetsuiteId = `99`;
        const givenNetsuiteRecordName = `recordName`;

        const expected = {
            status: 'success',
            method: `findXref`,
            model: `Category`,
            conditions: { 
                netSuiteId: 99, 
                netSuiteRecordName: `recordName` 
            }
        };

        const result = cache.getMagentoCategoryByNetSuiteId(
            givenNetsuiteId, 
            givenNetsuiteRecordName
        ).then( resp => {
            RootLogger.debug(`=== call completed!!! ===`);
            return resp;
        });

        expect(result).to.deep.equal(expected);
    });
Bill Turner
  • 869
  • 1
  • 13
  • 27
  • The value of `result` in your test will be the promise returned from your function not the value you are expecting. If you want to test that the promise resolves to `expected` you need to test that in the `then()` or use `async/await` in the test. – Mark Apr 24 '18 at 19:26
  • @Mark_M That seemed right, but it does not work. I neither get the log statement, nor the result of newly added statment in the then block: `expect({}).to.deep.equal(expected);`, which should fail. – Bill Turner Apr 24 '18 at 20:00
  • To be sure it was not comparing an empty object to another empty object, I changed the expect in my comment above to `expect({bad: 'error'}).to.deep.equal(expected);`. It still does not work. – Bill Turner Apr 24 '18 at 20:07
  • Are you using Mocha? If so, it needs to know you are waiting on an async operation in the test by using `done()` or returning the promise. See: https://mochajs.org/#asynchronous-code – Mark Apr 24 '18 at 20:09
  • 1
    @Mark_M you got me on the right track. And, you guessed right, I am using Mocha. I ended up using the second option in the accepted answer to this SO: [how-do-i-properly-test-promises-with-mocha-and-chai](https://stackoverflow.com/questions/26571328/how-do-i-properly-test-promises-with-mocha-and-chai). Sharing this link for others. – Bill Turner Apr 24 '18 at 21:19

0 Answers0