ts-mockito
ts-mockito copied to clipboard
New releases (2.6.7+) break tests
It seems that recent releases >= 2.6.7 introduced some bugs (if used with vitest?).
For example this does not work in 2.7.1 with vitest@1 or vitest@2:
import EventEmitter from 'node:events';
import {mock} from '@typestrong/ts-mockito';
import {describe, expect, it} from 'vitest';
class EventEmitterTest extends EventEmitter {}
describe('ts-mockito-test', () => {
const domainEventPublisherMock = mock(EventEmitterTest);
it('should mock', () => {
expect(domainEventPublisherMock).toBeDefined();
});
});
Errors
FAIL src/mocktest.spec.ts [ src/mocktest.spec.ts ]
SyntaxError: Unexpected token (11:29)
❯ toParseError node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parse-error.ts:74:19
❯ Parser.raise node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/tokenizer/index.ts:1497:19
❯ Parser.unexpected node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/tokenizer/index.ts:1537:16
❯ Parser.parseClassMemberWithIsStatic node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.ts:2062:12
❯ Parser.parseClassMember node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.ts:1881:10
❯ callback node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.ts:1794:14
❯ Parser.withSmartMixTopicForbiddingContext node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:3105:14
❯ Parser.parseClassBody node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.ts:1766:10
❯ Parser.parseClass node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.ts:1717:22
❯ Parser.parseStatementContent node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.ts:474:21
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { code: 'BABEL_PARSER_SYNTAX_ERROR', reasonCode: 'UnexpectedToken', loc: { line: 11, column: 29, index: 223, constructor: 'Function<Position>' }, pos: 223, clone: 'Function<clone>', details: { expected: null } }
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯
Everything works without problems with @typestrong/[email protected]
Seems not to be related to vitest. The library tests fail too if the following test is added:
import { EventEmitter } from "events";
import { mock } from "../src/ts-mockito";
class TestEmitter extends EventEmitter {}
describe("ts-mockito-test", () => {
const mocked = mock(TestEmitter);
it("should mock", () => {
expect(mocked).toBeDefined();
});
});
Output
Summary of all failing tests
FAIL test/bug.spec.ts
● Test suite failed to run
SyntaxError: Unexpected token (11:29)
at constructor (node_modules/@babel/parser/src/parse-error.ts:74:19)
at Parser.toParseError [as raise] (node_modules/@babel/parser/src/tokenizer/index.ts:1497:19)
at Parser.raise [as unexpected] (node_modules/@babel/parser/src/tokenizer/index.ts:1537:16)
at Parser.unexpected [as parseClassMemberWithIsStatic] (node_modules/@babel/parser/src/parser/statement.ts:2054:12)
at Parser.parseClassMemberWithIsStatic [as parseClassMember] (node_modules/@babel/parser/src/parser/statement.ts:1873:10)
at parseClassMember (node_modules/@babel/parser/src/parser/statement.ts:1786:14)
at Parser.callback [as withSmartMixTopicForbiddingContext] (node_modules/@babel/parser/src/parser/expression.ts:3106:14)
at Parser.withSmartMixTopicForbiddingContext [as parseClassBody] (node_modules/@babel/parser/src/parser/statement.ts:1758:10)
at Parser.parseClassBody [as parseClass] (node_modules/@babel/parser/src/parser/statement.ts:1709:22)
at Parser.parseClass [as parseStatementContent] (node_modules/@babel/parser/src/parser/statement.ts:471:21)
Yes, we changed the way we parse class code. I'll add this test to the ts-mockito test suite and verify that it works.
I just published 2.7.2, try to see if it works for you
Works for the given test case 🎉 Unfortunately there is another error for anonymous classes:
Serialized Error: { code: 'BABEL_PARSER_SYNTAX_ERROR', reasonCode: 'MissingClassName', loc: { line: 1, column: 6, index: 6, constructor: 'Function<Position>' }, pos: 6, clone: 'Function<clone>', details: {} }
Test case
import {mock} from '@typestrong/ts-mockito';
import {describe, expect, it} from 'vitest';
const TestClass = class {
private readonly foo = 'abc';
};
describe('anonymous class test', () => {
const testMock = mock(TestClass);
it('should be defined', () => {
expect(testMock).toBeDefined();
});
});
I see, if you have any other cases of broken tests I’ll add them all. Thanks for being patient with this release!!
edit - this is roypeled, just on my other account
I will, thank you for your great work! :)
@rezoled You're doing an amazing work! Unfortunately I'm not using the lib myself anymore (career changes) my attention is low, so your recent contributions are the best thing happened since the fork! 🙏
Works for the given test case 🎉 Unfortunately there is another error for anonymous classes:
Serialized Error: { code: 'BABEL_PARSER_SYNTAX_ERROR', reasonCode: 'MissingClassName', loc: { line: 1, column: 6, index: 6, constructor: 'Function<Position>' }, pos: 6, clone: 'Function<clone>', details: {} }Test case
import {mock} from '@typestrong/ts-mockito'; import {describe, expect, it} from 'vitest'; const TestClass = class { private readonly foo = 'abc'; }; describe('anonymous class test', () => { const testMock = mock(TestClass); it('should be defined', () => { expect(testMock).toBeDefined(); }); });
Hay @Jank1310, would you mind placing a breakpoint at the const testMock = mock(TestClass); line and print here to compiled code for the TestClass?
I'm trying to run this code locally and it works, probably because you are using vitest and I'm using Jest. If I could get the compiled code than I would be able to understand what went wrong.
In the meanwhile I'm testing other solutions
@Jank1310 can you try the latest version?
I'm not sure what you exactly need, but here is the value for TestClass
class {
constructor() {
this.foo = "abc";
}
}
You can test it on master with the following steps:
- npm i vitest
- Add anonymous test case
- npx vitest ./test/anonymous.spec.ts
=> Still throws A class name is required
Anonymous test case
import { describe, it } from "vitest";
import { mock } from "../src/ts-mockito";
const TestClass = class {
private readonly foo = "abc";
};
describe("anonymous class test", () => {
const testMock = mock(TestClass);
it("should be defined", () => {
expect(testMock).toBeDefined();
});
});
The latest version throws the following error for several test cases in my project (not exactly sure why this happens 😕 ):
SyntaxError: Unexpected token, expected "," (73:47)
❯ toParseError node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parse-error.ts:74:19
❯ Parser.raise node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/tokenizer/index.ts:1497:19
❯ Parser.unexpected node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/tokenizer/index.ts:1537:16
❯ Parser.expect node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/util.ts:150:28
❯ Parser.parseObjectLike node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:2070:14
❯ Parser.parseExprAtom node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:1193:21
❯ Parser.parseExprSubscripts node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:709:23
❯ Parser.parseUpdate node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:686:21
❯ Parser.parseMaybeUnary node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:649:23
❯ Parser.parseMaybeUnaryOrPrivate node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:390:14
With the latest release (2.7.3), we are also seeing errors in our Jest tests:
[2024-07-23T07:58:09.615Z] SyntaxError: Unexpected token, expected "," (190:54)
[2024-07-23T07:58:09.615Z]
[2024-07-23T07:58:09.615Z] 33 |
[2024-07-23T07:58:09.615Z] 34 | beforeEach(() => {
[2024-07-23T07:58:09.615Z] > 35 | someVar = mock(SomeClass);
[2024-07-23T07:58:09.615Z] | ^
[2024-07-23T07:58:09.615Z] TypeError: Cannot read properties of undefined (reading '__tsmockitoMocker')
[2024-07-23T07:58:09.615Z]
[2024-07-23T07:58:09.615Z] 38 |
[2024-07-23T07:58:09.615Z] 39 | afterEach(() => {
[2024-07-23T07:58:09.615Z] > 40 | reset(someVar);
[2024-07-23T07:58:09.615Z] | ^
Thanks for the examples everyone, I'm working on a solution for this.
Please try version 2.7.5, sorry again for this process. We changed the way ts-mockito parses classes, and it introduces several new edge cases.
@ghost91- , if it still doesn't work for you, can you provide the test and class being tested here?
2.7.5 throws the following error if executed with vitest
SyntaxError: Unexpected token, expected "," (11:52)
❯ toParseError node_modules/@babel/parser/src/parse-error.ts:74:19
❯ Parser.raise node_modules/@babel/parser/src/tokenizer/index.ts:1497:19
❯ Parser.unexpected node_modules/@babel/parser/src/tokenizer/index.ts:1537:16
❯ Parser.expect node_modules/@babel/parser/src/parser/util.ts:150:28
❯ Parser.parseObjectLike node_modules/@babel/parser/src/parser/expression.ts:2070:14
❯ Parser.parseExprAtom node_modules/@babel/parser/src/parser/expression.ts:1193:21
❯ Parser.parseExprSubscripts node_modules/@babel/parser/src/parser/expression.ts:709:23
❯ Parser.parseUpdate node_modules/@babel/parser/src/parser/expression.ts:686:21
❯ Parser.parseMaybeUnary node_modules/@babel/parser/src/parser/expression.ts:649:23
❯ Parser.parseMaybeUnaryOrPrivate node_modules/@babel/parser/src/parser/expression.ts:390:14
Test Case
import { describe, expect, it } from "vitest";
import { mock } from "../src/ts-mockito";
export class SimpleClass {
public async returnAsyncValue(): Promise<number> {
return 0;
}
}
describe("AsyncFunctions", () => {
const simpleMock = mock(SimpleClass);
it("should run", async () => {
expect(simpleMock).toBeDefined();
});
});
The reason seems to be the async function decleration
@Jank1310 thanks! I missed adding async functions to the tests. I'm preparing a fix
@Jank1310 please try 2.7.6, hopefully this is the final fix for this issue!
It fixes most errors but some errors still remain :/
Error:
SyntaxError: Unexpected token, expected "," (1282:57)
❯ toParseError node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parse-error.ts:74:19
❯ Parser.raise node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/tokenizer/index.ts:1497:19
❯ Parser.unexpected node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/tokenizer/index.ts:1537:16
❯ Parser.expect node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/util.ts:151:12
❯ Parser.parseObjectLike node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:2069:14
❯ Parser.parseExprAtom node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:1193:21
❯ Parser.parseExprSubscripts node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:709:23
❯ Parser.parseUpdate node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:686:21
❯ Parser.parseMaybeUnary node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:649:23
❯ Parser.parseMaybeUnaryOrPrivate node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/expression.ts:390:14
For the following test case
import { WorkflowClient } from "@temporalio/client";
import { describe, expect, it } from "vitest";
import { mock } from "../src/ts-mockito";
describe("Temporal WorkflowClient", () => {
const simpleMock = mock(WorkflowClient);
it("should run", async () => {
expect(simpleMock).toBeDefined();
});
});
It works if mock is changed to const simpleMock = mock<WorkflowClient>();
Testing. Probably more edge cases.
EDIT - found the bug, generator functions :) working on a fix
Ok, try 2.7.7 please
Looks good, no more errors 🎉
Finally! Thanks again for the patience and providing me with the edge cases!
Still facing the issue SyntaxError: Unexpected token, expected "," with 2.7.7 and this line :
rootElement = instance(mock({}));
^
Please try @rezoled 2.7.8
2.7.8. is still broken for us:
TypeError: Cannot read properties of null (reading 'type')
64 |
65 | beforeEach(() => {
> 66 | containerMock = mock(Container);
TypeError: Cannot read properties of undefined (reading '__tsmockitoMocker')
76 |
77 | afterEach(() => {
> 78 | reset(containerMock);
| ^
79 | reset(contextMock);
80 | });
81 |
where Container is imported from inversify.
@ghost91- Try 2.7.9
2.7.9 seems to work for the case I provided. Thanks!
Looks good now, as far as I can tell. Thanks!
Hey @roypeled,
we have found another problem: When using proxys (possibly only in combination with ts experimental decorators), we still get an error similar the above. It still works correctly in v2.6.6.
If necessary, I can try to create a minimal reproduction example.
Hey @ghost91- , thanks for letting me know. I’ll take a look at proxies. If you can, would you mind posting an example of a code with proxies that you are testing? That would help my identity the problem, thanks!