sinonjs / sinon

Test spies, stubs and mocks for JavaScript.

Home Page:https://sinonjs.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot stub static methods of class

hustlerman opened this issue · comments

Describe the bug
A clear and concise description of what the bug is.

Attempting to stub a static class method causes an error:
sandbox.stub(GameSession, 'create').callsFake(async () => { return "bye" })

export class GameSession { static async create(): String { return "hi" }

Test command and output:

TS_NODE_FILES=true mocha --require ts-node/register "test/**/*.ts"

  GameSessionControlle
    1) should create a game successfully

  0 passing (7ms)
  1 failing

  1) GameSessionController
       should create a game successfully:
     Error: Trying to stub property 'create' of undefined

Expected behavior
A clear and concise description of what you expected to happen.

Method to be stubbed successfully and return 'bye' when called

Context (please complete the following information):

Node: 18.13.0
Sinon: 15.0.4
@types/sinon: 10.0.14

  • Other libraries you are using:
    Mocha to run tests

Sinon clearly has no issue stubbing static methods (see this bug template I use on Runkit, for instance, as it does just that), so there's probably some details in your example that is off. Typescript issues is outside the scope of what we care about, but the repro seems small enough that I'll see what this is about 👍

I could not reproduce this in normal EcmaScript:

repro.mjs

import sinon from "sinon";

class GameSession {
  static async create() {
    return "hi";
  }
}

sinon.stub(GameSession, "create").callsFake(async () => {
  return "bye";
});

const result = await GameSession.create();
console.log(result);

Running it

$ node repro.mjs
bye

Unsurprisingly, I cannot reproduce using Typescript either.

$  TS_NODE_FILES=true npx mocha --require ts-node/register repro.test.ts


  ✔ this should not fail

  1 passing (3ms)

Here's the reproducible setup:

$ command cat package.json tsconfig.json  repro.test.ts
{
  "dependencies": {
    "mocha": "^10.2.0",
    "sinon": "^15.0.4",
    "ts-node": "^10.9.1"
  },
  "devDependencies": {
    "@types/mocha": "^10.0.1",
    "@types/sinon": "^10.0.14",
    "i": "^0.3.7"
  }
}
{
  "compilerOptions": {
    "esModuleInterop": true,
    "strict": true,
    "typeRoots": [
      "./node_modules/@types"
    ]
  }
}
import assert from "assert";
import sinon from "sinon";

class GameSession {
  static async create(): Promise<String>  {
    return "hi";
  }
}

it("this should not fail", async () => {
  const sandbox = sinon.createSandbox();

  sandbox.stub(GameSession, "create").callsFake(async () => {
    return "bye";
  });

  const result = await GameSession.create();

  assert.equal("bye", result);
});

The most likely issue with this (just a guess, as your example is not reproducible and hence is failing to recreate your environment this is failing in) is that you somehow fail to import or export the module correctly:

 Error: Trying to stub property 'create' of undefined

This means GameSession is undefined, which is not a problem with Sinon.