Closed mcous closed 3 years ago
That's an interesting use case there, mocking a React component like that. Pretty neat.
I'm pretty torn on this, all of the options are inelegant.
const _ = expect.anything()
calledWith({ xyz: '123' }, _)
calledWith({ xyz: '123' }, expect.anything())
partialCalledWith({ xyz: '123' }, expect.anything())
when(fn, { ignoreExtraArgs: true }).calledWith({ xyz: '123' }, expect.anything())
// Some more ideas
calledWith({ xyz: '123' }).ignoreExtraArgs()
calledWith(when.all(somePredicateFnThatReceivesAllArgsAndReturnsTrueOrFalse)) // this would build on the recent addition of Function matchers
All credit to @shlokamin on trying out that React component mock. This feature request comes from the both of us being very confused as to why when(FunctionComponent).calledWith(props)
wasn't working, only to discover React had been passing a second parameter in the whole time. Fun day!
all of the options are inelegant.
Yeah, there's a very pleasant terseness to the existing when
API. Throwing an options object in when
feels weird, and adding an entire new method like parialCalledWith
feels like a lot. I sorta gravitate towards calledWith({ xyz: '123' }).ignoreExtraArgs()
or something similar (e.g. withConfig
), but still...
Leaning on the function matchers seems pretty interesting, too, and might make userland solutions (or at least experimentation) easier.
overview
I'm a big fan of jest-when, and it makes using jest mocks far more pleasant than using them vanilla. I have a feature request (that I'd be very open to PR'ing, if you find it acceptable) to cover a particular usage that we've run into at my company.
Currently,
calledWith
requires all function arguments to be specified. For the vast majority of use cases, I think this is sensible and correct. I think there are, however, a small set of times when it would be nice to be able to omit arguments in the stub configuration, because they truly do not matter for the subject under test.Would you be open to adding an option to allow extra arguments to be ignored?
risks and alternatives
expect.anything()
or several could do the trick in most cases, at the expense of verbositymockImplementation
for these use caseswhen
andcalledWith
wrapper and deal with the problem in userlandprior art
testdouble.js, which has a very similar API to
jest-when
and seems to me to come from the same stubbing lineage, has anignoreExtraArgs
option during stub configuration.sinon.js does partial stubbing by default in its
calledWith
assertion. I think this is a bad default, but folks coming from Sinon would at least be familiar with this behavior.(Edit) after a deeper issue search that I should've completed before hitting submit, I ran into #36. I think this request is related, but distinct, because I'm talking specifically about rare cases where trailing arguments have no meaning to the subject nor stub.
actual use case
In this particular case, we're mocking out React function components. We have a collaborator component, and we want to verify that some child component is properly arranged with the correct props:
You (or rather, I) would expect this to work! However, it does not. For legacy reasons that have nothing to do with the code under test, the React rendering system passes two arguments the the
SomeChild
function,props
, and something else calledrefOrContext
. All of our function components are written to accept a single function parameter,props
, so the fact that React is passing in a second parameter doesn't do anything because it's always ignored.We can fix the test by doing...
...but it's a little more verbose and, more importantly to me, muddies how the test communicates its intent to the reader