代码之家  ›  专栏  ›  技术社区  ›  A Jar of Clay

测试子类的方法

  •  0
  • A Jar of Clay  · 技术社区  · 8 年前

    我正在尝试测试类A的方法X调用导入的函数Y。类A是类B的子类,应该模拟出来。

    A级看起来是这样的:

    const B = require('./B');
    const { Y } = require('../util');
    class A extends B {
      constructor() {
        super('/A');
        this.setCors('');
        this.app.post('', this.X.bind(this));
      }
    
      X(req, res) {
        Y();
      }
    }
    
    module.exports = A;
    

    尝试测试(如下 Jest Official Docs ):

    const A = require('../path/to/A');
    const B = require('../path/to/B');
    jest.mock('../path/to/B', () => {
      return jest.fn().mockImplementation(() => {
        return { setCors: jest.fn(), app: { post: jest.fn() } };
      });
    });
    
    test('method X calls function Y', () => {
      (new A()).X();
      expect(Y).toBeCalled();
    });
    

    这就产生了错误 TypeError: Cannot read property 'bind' of undefined 关于A的构造器。

    也许有必要仅模拟构造函数,但我不确定如何做到这一点。

    0 回复  |  直到 8 年前
        1
  •  0
  •   Lin Du Correcter    7 年前

    以下是解决方案:

    文件夹结构:

    .
    ├── A.spec.ts
    ├── A.ts
    ├── B.ts
    └── util.ts
    

    A.ts :

    import B from './B';
    import { Y } from './util';
    
    export default class A extends B {
      constructor() {
        super('/A');
        this.setCors('');
        this.app.post('', this.X.bind(this));
      }
    
      public X(req, res) {
        Y();
      }
    }
    

    B.ts :

    export default class B {
      public app = {
        post(route: string, controller: () => any) {
          //
        }
      };
      private name: string = '';
      private url: string = '';
      constructor(name: string) {
        this.name = name;
      }
    
      protected setCors(url: string) {
        this.url = url;
      }
    }
    

    util.ts :

    export function Y() {
      console.log('I am Y');
    }
    

    A.spec.ts :

    import A from './A';
    import { Y } from './util';
    
    jest.mock('./util.ts', () => {
      return {
        Y: jest.fn()
      };
    });
    
    const a = new A();
    
    describe('A', () => {
      it('should execute function Y correctly', () => {
        const mockedReq = {};
        const mockedRes = {};
        a.X(mockedReq, mockedRes);
        expect(Y).toBeCalledTimes(1);
      });
    });
    

    100%覆盖率的单元测试结果报告:

    PASS  src/stackoverflow/52075711/A.spec.ts (5.747s)
      A
        ✓ should execute function Y correctly (8ms)
    
    ----------|----------|----------|----------|----------|-------------------|
    File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    ----------|----------|----------|----------|----------|-------------------|
    All files |      100 |      100 |      100 |      100 |                   |
     A.ts     |      100 |      100 |      100 |      100 |                   |
     B.ts     |      100 |      100 |      100 |      100 |                   |
    ----------|----------|----------|----------|----------|-------------------|
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        9.623s, estimated 14s
    

    源代码: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/52075711

    推荐文章