Я борюсь с комбинацией Typescript и Jest, и, надеюсь, кто-то может мне помочь:
У меня есть следующий сценарий:
Я хочу протестировать функцию, которая используеткласс. Я хочу издеваться над классом.
Моя установка выглядит следующим образом:
src
- __mocks__
-- myClass.ts
- myClass.ts
- myFunc.ts
- myFunc.test.ts
Функция, которую я хочу протестировать
//myFunc.ts
import MyClass from './myClass';
export const myFunc = () => {
const c = new MyClass();
return c.doSomething();
};
// унаследованный класс, который я хочуиздеваться
//MyClass.ts
const MyClass = function() {};
MyClass.prototype.doSomething = function() {
return 'something';
};
export default MyClass;
Тест. Большая часть содержания здесь вдохновлена этим примером Jest . Я только что адаптировал его для TypeScript (в основном это @ ts-ignore)
//myFunc.test.ts
import {myFunc} from './myFunc';
//@ts-ignore
import {mockDoSomething} from './myClass';
jest.mock('./myClass');
mockDoSomething.mockReturnValueOnce('something from mock');
it('does something mocked', () => {
expect(myFunc()).toEqual('something from mock');
});
Но это не удается
FAIL src/myFunc.test.ts
✕ does something mocked (1ms)
● does something mocked
TypeError: myClass_1.default is not a constructor
2 |
3 | export const myFunc = () => {
> 4 | const c = new MyClass();
| ^
5 | return c.doSomething();
6 | };
7 |
at Object.<anonymous>.exports.myFunc (src/myFunc.ts:4:13)
at Object.<anonymous> (src/myFunc.test.ts:13:10)
Если я удаляю mocks / myClass. ts и измените myFunc.test.ts на
import {myFunc} from './myFunc';
const mockDoSomething = jest.fn();
jest.mock('./myClass', () => {
return {
default: jest.fn().mockImplementation(() => {
return {
doSomething: mockDoSomething
};
})
};
});
mockDoSomething.mockReturnValueOnce('something from mock');
it('does something mocked', () => {
expect(myFunc()).toEqual('something from mock');
});
Все работает как положено. Также предлагается здесь
Однако MyClass содержит много методов, которые я хочу смоделировать, поэтому использование отдельного файла в mocks кажется гораздо лучшим решением,и я действительно хочу, чтобы это работало.
Кроме того, я подозреваю, что одной из причин этого сбоя является тот факт, что MyClass.ts использует старый синтаксис. Это верно, так как это устаревший код (точнее, ветка ADAL.js ). Я действительно не хочу переписывать этот код. И нет, MSAL тоже не вариант.
Требуемая тестовая настройка работала нормально, прежде чем я преобразовал все в машинописный текст.
Детали:
//depencencies
"ts-jest": "^24.1.0",
"typescript": "^3.6.4"
//tsconfig.json
{
"compilerOptions": {
"outDir": "build",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom", "es2016", "es2017"],
"sourceMap": false,
"moduleResolution": "node",
"declaration": true,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": false,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"allowSyntheticDefaultImports": true
},
"include": ["src"],
"exclude": ["node_modules", "build", "**/__mocks__", "**/*.test.ts"]
}