简体   繁体   中英

How to test called promises not returned in tested function

First of all, I've been trying almost everything to make this code work, and I achieved, the problem is that I don't like the approach, and I wanted to know if there was something better I could do in order to make the TEST code more readable, but functional.

I want to assert (with sinon for example) that the second function ( secondApiCall ) has been called , but it seems like there is no way to make that happen, how would you make it happen. Is it there a non hacky approach?

The main problem here is that "I can't modify the functionToTest " and I have to write tests that would be basically checking that the API calls are being done.

How with the given code would you run the assertions after functionToTest has finished?

PS: The code is shit, I know, but sometimes you just have to deal with it, you can't do more thank just test the shit out of it before refactoring it :(

const firstApiCall = () => {
    return new Promise(function(resolve,reject) {
        setTimeout(() => {
            resolve('firstApiCall success');
        }, 3);
    });
};

const secondApiCall = () => {
    return new Promise(function(resolve,reject) {
        setTimeout(() => {
            resolve('secondApiCall success');
        }, 3);
    });
};

const functionToTest = () => {
    setTimeout(() => {
        firstApiCall().then(result => {
                setTimeout(() => {
                    secondApiCall()
                }, 2)
            })
    }, 15)
};

Basically the code that generates the mocks does something like this, so at the end you have synchronous code

const firstApiCall = () => {
    return {
        then: (cb) => {
            cb('firstApiCall success')
        }
    }
};

Thank you very much!

You cannot check that the second API call did happen directly, unless the Promise is returned.

As described here:

const functionToTest = () => {
  setTimeout(() => {
    firstApiCall().then(result => {
      setTimeout(() => {
        secondApiCall()
      }, 2)
    })
  }, 15)
};

the Promise is not returned so there's nothing you can do about it IMHO.

Mocking the function is not useful here I'd say.

If you cannot test it directly, you can try to test it indirectly: even if it's pretty bad, you could check via the API the function is calling, that the state of the resource behind the API has changed as expected after the second call. If you cannot test via the API well... there's no much to test then.

After trying a couple of things, what you can always do, is mock the first API call, so at the end instead of an async call you would have a sync one thanks to callbacks, I will leave here an example, for whoever needs inspiration when testing promises that are not returned.

const firstApiCall = () => {
    return {
        then: (callback) => {
            callback('firstApiCall success');
        }
    }
};

PS: Once again, this solution is not the prettiest but it works at least.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM