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

Can't use Promise.reject with 'and.returnValues()' #1783

Open
coyoteecd opened this issue Feb 3, 2020 · 1 comment
Open

Can't use Promise.reject with 'and.returnValues()' #1783

coyoteecd opened this issue Feb 3, 2020 · 1 comment

Comments

@coyoteecd
Copy link

I am trying to spy on an async function that gets called twice; first time I'd like to return a rejected Promise and second time a resolved one. I've read through the comments in #1590; the callFake() is something I use for the simple case where I just want to just return a rejected promise all the time. But that won't work with multiple calls.

Of course, one workaround is to use callFake() in combination with a counter in the test spec and conditionally return a resolved/rejected promise based on the counter. But this reduces the test readability and is just a pain to do more than once. I feel the library should provide a better way.

Expected Behavior

One option could be to introduce a callFakes() that accepts multiple callbacks and calls them in order, similar to what .and.returnValues() does. This way I can conveniently write:

spyOn(obj, 'asyncMethod').and.callFakes(
 () => Promise.reject('bad'),
 () => Promise.resolve()
);

which in my opinion looks good and can even be used for other things.

Note: after writing this I did a search on callFakes and it turned out this has been proposed before, see #1688 (comment). Would this be something we want in jasmine then?

@slackersoft
Copy link
Member

If possible, I'd still like to see something more general (as I mentioned). This would also allow mixing and matching strategies, instead of requiring the use of a full fake function. To bring those suggestions inline here too, something like:

request.get.and.rejectWith(new Error('404'))
    .andThen.rejectWith(new Error('404'))
    .andThen.resolveTo('OK')

or:

request.get.and.do(
  (call) => call.rejectWith(new Error('404')),
  (call) => call.rejectWith(new Error('404')),
  (call) => call.resolveTo('OK')
)

The first option feels more fluent, but will probably be more complicated to implement. I think either would be fine and I'm happy to discuss what feels better to the community as well.

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

No branches or pull requests

3 participants