1

I have this simple middle layer code which will be called by someone and it is calling some other api which is returning Promise

function getSomething() {
  return api.fetchSomething()
    .then(response => response)
}

To test this I wrote this test which is passing.

it('should make a call to api method ', () => {
        const someResponse = {};
        const fetchSomethingStub = sandbox.stub(api, 'fetchSomething').returns(Promise.resolve(someResponse));
        const someResult = getSomething();

        someResult.then((result) => {
            expect(fetchSomethingStub ).to.have.callCount(1);
            expect(result).to.eventually.equal(someResponse);
        });
    });

But since my api.fetchSomething() can return reject too I changed the stub to return Promise.reject but test is passing but with message (node:14688) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): [object Object]. Is that mean I have to have catch block in this layer to.? I am planning to just pass on the value from api. Also I am doing test correctly for promise. Any suggestion with resource to look for Promise test with mocha is appreciated.

αƞjiβ
  • 3,056
  • 14
  • 58
  • 95
  • The `.then(response => response)` part is pointless. Omit it. – Bergi Feb 07 '17 at 01:45
  • @Bergi is that also mean both resolve and reject will be pass back tot he claler and that elimiate the way to need for test? – αƞjiβ Feb 07 '17 at 19:47
  • Yes, both fulfillment and rejection would be passed through directly. If you are already testing `api.fetchSomething()`, then testing `getSomething()` might be useless indeed (though an assertion that they do the same could be nice) – Bergi Feb 07 '17 at 19:54

1 Answers1

0

So fundamentally you have an unhandled exception in this code. If you really want to test the behavior in the rejection case, then yes, you'll need a test that has a .catch handler. If the promise is rejected, the .then handler is never called so your asserts won't happen.

The other thing you can do is change this line:

    someResult.then((result) => {

to

    return someResult.then((result) => {

This returns the promise back out to the Mocha runner and lets it properly detect a failed test where the promise was rejected unexpectedly.

Without it you also have a synchronization bug in your test - Mocha doesn't know to wait for async stuff to finish before reporting the results. Returning the promise hooks you correctly into the test runner & result reporting.

Chris Tavares
  • 29,165
  • 4
  • 46
  • 63
  • Technically I believe, you can actually handle the error with a function in the thenable: .then((res) => {}, (rej) => {}), but this is discouraged for multiple reasons. Catch is definitely how you want to handle this; agreed. – thesublimeobject Feb 07 '17 at 00:58
  • @thesublimeobject No, it's not discouraged, have a look at the [difference between `.then(…).catch(…)` and `.then(…, …)`](http://stackoverflow.com/q/24662289/1048572). If your test wants to distinguish fulfilments from rejections, you should use `then` with two callbacks. – Bergi Feb 07 '17 at 01:48