midway icon indicating copy to clipboard operation
midway copied to clipboard

服务单元测试无法获得父类方法

Open ddzyan opened this issue 2 years ago • 23 comments

image

在对 service 单元测试的时候,无法获得 service 从父类继承的方法,具体代码如下

import { relative } from 'path';
import * as assert from 'assert';

import { testConfig } from '../root.config';
import { ClassroomService } from '../../src/app/service/classroom';

const filename = relative(process.cwd(), __filename).replace(/\\/gu, '/');

describe(filename, () => {
  it('should create', async () => {
    const classroomService = await testConfig.app
      .getApplicationContext()
      .getAsync<ClassroomService>(ClassroomService);

    const res = await classroomService.create({ grade: 1, prom: 2 });
    assert(res);
  });
});

classroom.ts 定义如下,BaseService 中已经定义了 create 方法

import { Provide, Inject } from '@midwayjs/decorator';
import { SequelizeDataSourceManager } from '@midwayjs/sequelize';

import { BaseService } from '@/core/baseService';
import { ClassroomMapping } from '../mapping/classroom';
import { UserMapping } from '../mapping/user';

@Provide()
export class ClassroomService extends BaseService {
  @Inject()
  protected mapping: ClassroomMapping;

  @Inject()
  private sequelizeDataSourceManager: SequelizeDataSourceManager;

  @Inject()
  protected userMapping: UserMapping;

  async destroyClassroomAndUser(classroomId: number) {
    const t = await this.sequelizeDataSourceManager
      .getDataSource('default')
      .transaction();
    try {
      await this.mapping.destroy({ id: classroomId }, t);
      await this.userMapping.destroy({ classroomId }, t);
      await t.commit();
      return true;
    } catch (error) {
      await t.rollback();
      throw error;
    }
  }
}

ddzyan avatar Jul 26 '22 07:07 ddzyan

const res = await classroomService.create({ grade: 1, prom: 2 });

这儿的 classroomService 的类型好像是 any

waitingsong avatar Jul 26 '22 07:07 waitingsong

这代码咋修改呢? 没什么思路

ddzyan avatar Jul 26 '22 07:07 ddzyan

baseService 里有 create ? 不是public ?

czy88840616 avatar Jul 26 '22 09:07 czy88840616

下面这个是 baseService 的代码

import { App, Inject } from '@midwayjs/decorator';
import * as koa from '@midwayjs/koa';

export abstract class BaseService {
  @App()
  protected app: koa.Application;

  @Inject()
  protected ctx: koa.Context;

  protected mapping;

  async findAndCountAll(page: number, limit: number, where = {}) {
    const res = await this.mapping.findAndCountAll(page, limit, where);
    return res;
  }

  async findAll(where = {}, options = {}) {
    const res = await this.mapping.findAll(where, options);
    return res;
  }

  async findOne(where) {
    const res = await this.mapping.findOne(where);
    return res;
  }

  async create(createParams) {
    const res = await this.mapping.saveNew(createParams);
    return res;
  }

  async update(updateParams, where) {
    const res = await this.mapping.modify(updateParams, where);
    return res;
  }

  async destroy(where) {
    const res = await this.mapping.destroy(where);
    return res;
  }

  async findByPk(id: number) {
    const res = await this.mapping.findByPk(id);
    return res;
  }
}

ddzyan avatar Jul 26 '22 10:07 ddzyan

代码仓库:https://github.com/ddzyan/midway-practice.git ,分支是 unitTest

ddzyan avatar Jul 26 '22 10:07 ddzyan

@waitingsong 这个报错你遇到过吗 image

ddzyan avatar Jul 27 '22 09:07 ddzyan

@waitingsong 这个报错你遇到过吗 image

你看看你那儿 node 和 tsc, ts-node 的版本是多少

waitingsong avatar Jul 27 '22 14:07 waitingsong

再看看 node_modules 下面第一级目录中有没有 koid 目录 截图执行的是啥命令?

waitingsong avatar Jul 27 '22 14:07 waitingsong

主题的问题这样解决: import { BaseService } from '@/core/baseService'; 改成 import { BaseService } from '../../core/baseService';

waitingsong avatar Jul 27 '22 14:07 waitingsong

再看看 node_modules 下面第一级目录中有没有 koid 目录 截图执行的是啥命令?

一级目录是有 koid 目录的, 运行的是 npm test 对应的是 midway-bin test --ts -f test/comm/email.test.ts

ddzyan avatar Jul 27 '22 14:07 ddzyan

第二个解决办法是修改 tsconfig.json

"exclude": ["dist", "node_modules", "test"] 删除掉 test 当然,这样在 build 的时候也会编译 test 目录。 我的办法是在 test 目录下新创一个 tsconfig.json ,引用上级目录的相同文件,然后在include中包括本目录

waitingsong avatar Jul 27 '22 14:07 waitingsong

midway-bin test --ts -f test/comm/email.test.ts

没有 email.test.ts 这个文件。 并且 pkg.scripts 中是这样

"test": "midway-bin test --ts --mocha",

waitingsong avatar Jul 27 '22 14:07 waitingsong

midway-bin test --ts -f test/comm/email.test.ts

没有 email.test.ts 这个文件。 并且 pkg.scripts 中是这样

"test": "midway-bin test --ts --mocha",

这是我另外一个内部项目,不在上面的示例仓库中,运行指令这样配置是因为我要指定执行某个个单元测试文件

ddzyan avatar Jul 27 '22 14:07 ddzyan

@waitingsong 这个报错你遇到过吗 image

你看看你那儿 node 和 tsc, ts-node 的版本是多少

对应的版本号是 node v16.14.2 tsc Version 4.7.4 ts-node 10.9.1

ddzyan avatar Jul 28 '22 02:07 ddzyan

第二个解决办法是修改 tsconfig.json

"exclude": ["dist", "node_modules", "test"] 删除掉 test 当然,这样在 build 的时候也会编译 test 目录。 我的办法是在 test 目录下新创一个 tsconfig.json ,引用上级目录的相同文件,然后在include中包括本目录

我尝试去除了 test 配置,但是没有什么效果

ddzyan avatar Jul 28 '22 02:07 ddzyan

主题的问题这样解决: import { BaseService } from '@/core/baseService'; 改成 import { BaseService } from '../../core/baseService';

这个问题解决了,感觉是不是不太推荐在代码中是用 @ 呢

ddzyan avatar Jul 28 '22 02:07 ddzyan

去除了 test 配置

好像还需要把 module 从 es2018 升级到 es2019 及以上。

waitingsong avatar Jul 29 '22 09:07 waitingsong

现在卡在这个模块包的报错了,问题你遇到过吗? @waitingsong image

ddzyan avatar Jul 29 '22 12:07 ddzyan

试试把 module 修改高一些看看,比如 ES2020

waitingsong avatar Jul 29 '22 13:07 waitingsong

@ddzyan 个人是不太喜欢用 alias的,毕竟不是标准的能力,而是靠三方包或者编译时做的一些hack来变的,不过node新版本已经慢慢加入了 exports 的能力,后续 ts 类型支持好了的话,我觉得就没问题了。

czy88840616 avatar Jul 30 '22 04:07 czy88840616

node 新版本支持 import 别名,以后应该就能解决问题了

waitingsong avatar Jul 30 '22 12:07 waitingsong

@waitingsong 升级到 es2020 现在变成下面这个问题了,又遇到过吗... image

ddzyan avatar Aug 02 '22 02:08 ddzyan

@waitingsong 升级到 es2020 现在变成下面这个问题了,又遇到过吗... image

来个复现库我看看

waitingsong avatar Aug 02 '22 04:08 waitingsong

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Aug 21 '23 09:08 github-actions[bot]