Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stubbing sequential promise results #478

Closed
billtong opened this issue Jan 5, 2022 · 7 comments · Fixed by #481
Closed

Stubbing sequential promise results #478

billtong opened this issue Jan 5, 2022 · 7 comments · Fixed by #481

Comments

@billtong
Copy link

billtong commented Jan 5, 2022

description

I want to suggest an enhancement about thenReject and thenResolve function. In the older version before 3.14. when I want to do a sequential promise return I can do thenReturn(Promise.resolve('value1'), Promise.reject(Error('error1'))). However, now it forced me to use thenReject and thenResolve for stubbing promise, I can't actually achieve it easily with these two functions. As the code shows below. it will always return the last stubbing promise result. I was expecting that it will be the same sequence as I stubbing them.

Right now I fix this problem by introducing a counter and thenDo function. Still, It's way messier than before. I hope it can be achieved by calling thenReject and thenResolve function in a more natural way.

demo

env:

  • node version 12.22.5
  • testdouble version 3.16.4
const fetch = td.function();
td.when(fetch('test')).thenReject(Error('error1'));
td.when(fetch('test')).thenReject(Error('error2'));
Array.from(Array(2)).forEach((x, i) => {
    fetch('test').catch((error: Error)=>{
        console.debug(error.message);
    })
});
// console log I'm expecting error1 then error2
// error2
// error2
// I'm expecting error1 then error2

td.when(fetch('test')).thenResolve('return1');
td.when(fetch('test')).thenResolve('return2');
Array.from(Array(2)).forEach((x, i)=> {
    fetch('test').then((value: string) => {
        console.log(value);
    });
});
//console log
// return2
// return2
//I'm expecting return1 then return2

const fetch = td.function();
td.when(fetch('test')).thenResolve('return1');
td.when(fetch('test')).thenReject(Error('error1'));
Array.from(Array(2)).forEach((x, i) => {
    fetch('test')
    .then((value:string) => {
        console.debug(value);
    })
    .catch((error: Error)=>{
        console.debug(error.message);
    })
});
//console.log
// error1
// error1
//I'm expecting return1 then error1
@searls
Copy link
Member

searls commented Jan 5, 2022

Can you point to the version of td.js that broke your usage? It looks like 3.14 was just typescript definition updates

@billtong
Copy link
Author

billtong commented Jan 6, 2022

Can you point to the version of td.js that broke your usage? It looks like 3.14 was just typescript definition updates

I have this problem after updating to the latest version 3.16.4

@searls
Copy link
Member

searls commented Jan 6, 2022

Could you tell me what version did work for you so we can bisect the change that's affecting your case?

@billtong
Copy link
Author

billtong commented Jan 6, 2022

It worked at version 3.13.1, and it's not after I updated it to 3.16.4. Sorry for the unclear description.

my old code at version 3.13.1

td.when(mockDynamo.update(putLockParams))
  .thenReturn(Promise.reject({ code: conditionalCheckFailedException }), Promise.resolve({ Attributes: dbRecord }));

my new code at version 3.16.4 in order to achieve the same sequence of stubbing results. It works but, I'd prefer if such workaround was not needed.

let tryCount = 0;
td.when(mockDynamo.update(putLockParams))
    .thenDo(() => {
        tryCount++;
        if(tryCount === 1) {
            return Promise.reject({ code: conditionalCheckFailedException });
        } else {
            return Promise.resolve({ Attributes: dbRecord });
        }
    });

@johnbotris
Copy link
Contributor

I've also come up on this issue and would like a resolution.

Can you point to the version of td.js that broke your usage? It looks like 3.14 was just typescript definition updates

The introduction of PromiseStubber seems to be what has made this impossible.

Perhaps adding something like

...
  thenReturn<T>(first: Promise<R>, ...args: Array<Promise<R>>): TestDouble<T>;
...

to PromiseStubber's definition might be the solution, although I'm not sure if it would fit. I'd be happy to look into it

@searls
Copy link
Member

searls commented Mar 1, 2022

Since I don't use typescript, I'd really appreciate any help, @johnbotris

@billtong
Copy link
Author

billtong commented Mar 1, 2022

@johnbotris, I like your idea. It can solve the problem and not confuse the type check between promise stub and regular stub. I'd love to help review and test your code after you make changes to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants