TypeScript: Sinon stubbing failed after upgrade to 3.9.2

TypeScript Version: 3.9.2, 3.9.3

Search Terms: sinon, stub

Code

// file: ./src/stubber/index.ts
export { toStub } from './to-stub'

// file: ./src/stubber/to-stub.ts
export const toStub = () => {
  console.log('real stub')
}

// file: ./src/start.ts
import * as sinon from 'sinon'
import * as stubber from './stubber'
(async () => {
  sinon.stub(stubber, 'toStub').callsFake(() => {
    console.log('fake stub')
  })
  stubber.toStub()
})()

Run the start.ts script by compiling it with tsc or simply use ts-node. I’d expect it print fake stub but now it prints real stub. It’s working as expected for typescript@3.8 or lower, start breaking from 3.9.2.

Expected behavior:

Print “fake stub”

Actual behavior:

Print “real stub”

Playground Link: Can’t provide Playground link because it contains multiple files

Related Issues: Nope

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 12
  • Comments: 18 (3 by maintainers)

Commits related to this issue

Most upvoted comments

I found this code to break when upgrading from 3.8.2 to 3.9.2. We use ts-jest to transform our TypeScript Jest tests.

import * as foo from 'some/path'
jest.spyOn(foo, 'bar');

I would get an error like:

<spyOn> : bar is not declared writable or has no setter

I resolved this by doing this workaround:

jest.mock('some/path', () => ({
  ...jest.requireActual('some/path'),
}));
const foo = require('some/path');

It’s not pretty, but it at least unblocked me from upgrading.

@AndyOGo see https://github.com/jasmine/jasmine/issues/1817#issuecomment-823329763 for an easy workaround monkey-patching tslib. I’m using this hack across 40 packages (Node.js and browser), works perfectly. This should work with any testing library supporting import mocking.

I did a similar thing with babel, https://github.com/snyk/babel-plugin-mutable-imports , but ended up just forking sinon to make it warn, and fixing all the code. https://github.com/sinonjs/sinon/pull/2319

Yeah, having the same issue, very annoying 👍

ES module exports are specified to not be enumerable, so this is the expected behavior. Prior behavior was out of compliance with the spec.

The same problem exists for jasmine’s spys. I tracked the problem down to this change https://github.com/microsoft/TypeScript/pull/32264. After this change get and set properties of modules imported with star syntax are no longer enumerable which then causes a crash in jasmine’s check here. Most likely the same can be said for Sinon and I also saw a comment from someone having this problem with jest here.

Should we tell those libraries to adapt their code or can we have a flag to keep those properties enumerable?