首页 > 解决方案 > 如何测试返回“this”的初始化方法,其中只有一个 if 条件来设置内部数据

问题描述

我试图弄清楚如何测试这种方法

// Let's say models === null when we instantiate
public initialize(mongodb: MongoDb): this {
    if (!this.models) {
      this.models = {
        users: new models.UserModel(mongodb),
      };
    }
    return this;
  }

  public getModels(): Models | null {
    return this.models || null;
  }

我的报道仍然停留在我没有测试 if 部分......这不是真的,因为当我要求时,getModels我可以测试它的值(所以隐含的 if.

任何想法?

标签: javascripttypescripttestingjestjs

解决方案


这是解决方案:

index.ts

import * as models from './models';
import { MongoDb, Models } from './interfaces';

export class UserDataSource {
  private models: Models | null = null;
  public initialize(mongodb: MongoDb): this {
    if (!this.models) {
      this.models = {
        users: new models.UserModel(mongodb)
      };
    }
    return this;
  }

  public getModels(): Models | null {
    return this.models || null;
  }
}

单元测试,index.spec.ts

import { UserDataSource } from './';
import { MongoDb } from './interfaces';
import * as models from './models';

describe('UserDataSource', () => {
  const mockedMongodb: MongoDb = {};
  describe('#initialize', () => {
    it('should initlialize models correctly', () => {
      const userDataSource = new UserDataSource();
      const actualValue = userDataSource.initialize(mockedMongodb);
      expect(userDataSource.getModels()).toEqual(expect.objectContaining({ users: expect.any(models.UserModel) }));
      expect(actualValue).toBe(userDataSource);
    });
    it('should not initialize models', () => {
      const userDataSource = new UserDataSource();
      // tslint:disable-next-line: no-string-literal
      userDataSource['models'] = [];
      const actualValue = userDataSource.initialize(mockedMongodb);
      expect(actualValue).toBe(userDataSource);
    });
  });

  describe('#getModels', () => {
    it('should get models correctly', () => {
      const userDataSource = new UserDataSource();
      const actualValue = userDataSource.getModels();
      expect(actualValue).toEqual(null);
    });

    it('should get models correctly and not null', () => {
      const userDataSource = new UserDataSource();
      // tslint:disable-next-line: no-string-literal
      userDataSource['models'] = [];
      const actualValue = userDataSource.getModels();
      expect(actualValue).toEqual([]);
    });
  });
});

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

 PASS  src/stackoverflow/52729002/index.spec.ts
  UserDataSource
    #initialize
      ✓ should initlialize models correctly (5ms)
      ✓ should not initialize models (7ms)
    #getModels
      ✓ should get models correctly (1ms)
      ✓ should get models correctly and not null (1ms)

-----------------|----------|----------|----------|----------|-------------------|
File             |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------------|----------|----------|----------|----------|-------------------|
All files        |      100 |      100 |      100 |      100 |                   |
 52729002        |      100 |      100 |      100 |      100 |                   |
  index.ts       |      100 |      100 |      100 |      100 |                   |
 52729002/models |      100 |      100 |      100 |      100 |                   |
  UserModel.ts   |      100 |      100 |      100 |      100 |                   |
  index.ts       |      100 |      100 |      100 |      100 |                   |
-----------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        6.157s

这是完成的演示:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/52729002


推荐阅读