【问题标题】:Test invalid function arguments with TypeScript and JestJS使用 TypeScript 和 JestJS 测试无效的函数参数
【发布时间】:2019-11-04 10:39:07
【问题描述】:

我已经使用 typescript 创建了一个节点应用程序,并且正在使用 jest 编写单元测试。

我的问题:我不能真正编写模拟无效函数参数类型的单元测试,因为 typescript 不会编译。我的意思是很高兴 typescript 意识到我试图在这些函数中输入错误的数据,但到目前为止我理解 ts 的方式是,它只在编译期间有效。在运行时不会对参数类型进行任何检查。

所以我仍然必须用 jest 来测试我的 IO 依赖函数的正确行为,对吗?

我想我只需要编写一个 xyz.spec.js 并留下所有接口和类型以进行特定测试。但是后来我收到了一个关于导入模块的错误。我猜是因为它不是 ts 文件。

我是否必须更改我的 jest 或 ts 设置才能使其正常工作?

这是测试和错误的截图:

这里是我的 package.json:

{
  "name": "state",
  "version": "0.0.0",
  "files": [
    "build"
  ],
  "main": "build/index",
  "types": "build/index",
  "scripts": {
    "clean": "rimraf build && rimraf coverage",
    "format": "prettier --write \"{src,__tests__}/**/*.ts\" --single-quote --trailing-comma es5",
    "lint": "tslint --force --format verbose \"src/**/*.ts\"",
    "prepublishOnly": "npm run build",
    "start": "node ./build/index.js",
    "prebuild": "npm run clean && npm run format && npm run lint && echo Using TypeScript && tsc --version",
    "build": "tsc --pretty",
    "build:watch": "nodemon --legacy-watch src/index.ts",
    "test": "jest --no-cache",
    "test:watch": "jest --no-cache --watch",
    "coverage": "jest --no-cache --coverage"
  },
  "dependencies": {
    "mongoose": "^5.6.0"
  },
  "devDependencies": {
    "@types/jest": "^24.0.13",
    "@types/mongoose": "^5.5.6",
    "@types/node": "^10.14.7",
    "coveralls": "^3.0.2",
    "jest": "^24.8.0",
    "nodemon": "^1.19.0",
    "prettier": "^1.14.3",
    "rimraf": "^2.6.2",
    "ts-jest": "^24.0.2",
    "ts-node": "^8.1.0",
    "tslint": "^5.11.0",
    "tslint-config-prettier": "^1.15.0",
    "typescript": "^3.1.1"
  },
  "engines": {
    "node": ">=10.0.0"
  },
  "jest": {
    "preset": "ts-jest"
  }
}

这里是我的 tsconfig.json:

{
  "compilerOptions": {
    "declaration": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "lib": ["esnext"],
    "target": "es2015",
    "outDir": "./<%= buildpath %>",
    "removeComments": true,
    "inlineSourceMap": true,
    "inlineSources": true,
    "preserveConstEnums": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "build"]
}

最好的问候 特征

【问题讨论】:

    标签: typescript jestjs


    【解决方案1】:

    您可以在测试的参数中使用as any。这样您就可以添加“错误”类型并用它测试您的代码。例如,假设您要测试需要某种 Prop 对象的 someFunction() 函数

    interface Prop {
        id: number;
        type: string;
    }
    
    function someFunction(props: Prop): void {
        // ... do some stuff
    }
    

    那么你的测试可能看起来像这样:

    it('should not accept the wrong argument type', () => {
        const props = { id: 123 };
        const testSomeFunction = () => {
            someFunction(props as any);
        };
        expect(testSomeFunction).toThrow();
    });
    

    您还可以查看 Type Guards,以进行运行时类型检查: http://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types

    function isValidProp(prop: Prop): prop is Prop {
        const keys = ['id', 'type'];
        return Object.keys(prop).every(key => keys.includes(key));
    }
    
    function someFunction(props: Prop): void {
        if(!isValidProp(prop)){
            throw new Error('invalid prop!');
        }
        // ... do some stuff
    }
    

    【讨论】:

      【解决方案2】:

      它最终为我解决的问题是允许 js 用于 typescript。所以我的新 tsconfig.json 看起来像这样:

      {
        "compilerOptions": {
          "module": "commonjs",
          "moduleResolution": "node",
          "lib": ["esnext"],
          "target": "es2015",
          "outDir": "./build",
          "removeComments": true,
          "inlineSourceMap": true,
          "inlineSources": true,
          "preserveConstEnums": true,
          "experimentalDecorators": true,
          "emitDecoratorMetadata": true,
          "strict": true,
          "noUnusedLocals": true,
          "noUnusedParameters": true,
          "noImplicitReturns": true,
          "noFallthroughCasesInSwitch": true,
          "allowJs": true
        },
        "include": ["src/**/*"],
        "exclude": ["node_modules", "build"]
      }
      

      【讨论】:

        猜你喜欢
        • 2018-09-04
        • 2018-06-13
        • 2018-06-12
        • 2019-03-10
        • 2018-02-24
        • 1970-01-01
        • 2019-03-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多