Sinon: Make spy properties non-enumerable

Created on 25 Oct 2018  路  12Comments  路  Source: sinonjs/sinon

Is your feature request related to a problem? Please describe.
When a Sinon spy assertions fails during unit testing, some assertion libraries like power-assert (used by Ava) will print all the spy properties (including the spy methods) which is very verbose and makes it harder to see why the test failed.

Describe the solution you'd like
Make Sinon-specific spy properties non-enumerable.

Describe alternatives you've considered

  • customizing the assertion library power-assert but it's hard to do from Ava
  • customizing Ava but it's not possible because it directly relies on power-assert for this case
  • overriding spy[Symbol.toStringTag] or spy.toJSON() but this does not work since power-assert does not use either. Instead it iterates over enumerable properties.

Additional context
The feature request is about spies, but it most likely can be related to other Sinon objects, such as stubs and fakes.

Here's a screenshot of how verbose a single test Sinon assertion can become with Ava:

enumerable_properties

All 12 comments

How would this affect REPL usage and API discoverability? One of my favorite ways of using new tech is through exploratory testing on the REPL. Doing var spy = sinon.spy(); spy. and then tab-ing my way through the various methods. Would this still work?

Yes, non-enumerable properties are still shown on tab autocomplete in Node.js REPL.

I think this would be a good improvement, and can't currently think of any downsides.

This has been implemented with #1941 and released as [email protected]

Thanks for this!

However I do not think this worked:

> sinon.spy()
{ [Function: proxy]
  isSinonProxy: true,
  called: false,
  notCalled: true,
  calledOnce: false,
  calledTwice: false,
  calledThrice: false,
  callCount: 0,
  firstCall: null,
  secondCall: null,
  thirdCall: null,
  lastCall: null,
  args: [],
  returnValues: [],
  thisValues: [],
  exceptions: [],
  callIds: [],
  errorsWithCallStack: [],
  displayName: 'spy',
  toString: [Function: toString],
  instantiateFake: [Function: create],
  id: 'spy#0' }

> Object.keys(sinon.spy())
[ 'isSinonProxy',
  'called',
  'notCalled',
  'calledOnce',
  'calledTwice',
  'calledThrice',
  'callCount',
  'firstCall',
  'secondCall',
  'thirdCall',
  'lastCall',
  'args',
  'returnValues',
  'thisValues',
  'exceptions',
  'callIds',
  'errorsWithCallStack',
  'displayName',
  'toString',
  'instantiateFake',
  'id' ]

Those keys are still enumerable.

As a consequence the original problem still arises.

@ehmicky which version of sinon are you using to produce that output?

I am using Sinon 7.1.1, Node 11.3.0, Ubuntu 18.10.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Bumping because this issue is still valid with Sinon 7.2.3, Node 11.9.0, Ubuntu 18.10.

Ah, @LouisBrunner explicitly just made the _functions_ non-enurable. The other non-function properties are still enumerable. Don't you still want to see those props?

To make the props non-enurable, as well, you would have to use Object.defineProperties on the list of props that are created here.

Seems quite doable. Feel up to it, @ehmicky? A lot more likely it will be done if you are scratching your own itch :-)

Here you go: #1975

Ended up being more than one place to modify.

Was this page helpful?
0 / 5 - 0 ratings