Jasmine 在测试另一个 class 时替换 class

Jasmine replace class while testing another class

我有一个普通的旧 class,不是组件,我想用这个方法测试

static fromJson(json: any): ClientDTO {
    const ret: ClientDTO = Object.assign(new ClientDTO(), json)

    const dp = new DateWithoutTimePipe()

    ret.contractStart = dp.transform(json.contractStart)
    ret.contractEnd = dp.transform(json.contractEnd)

    return ret
}

作为测试方法的一部分,我想验证是否使用预期参数调用了转换方法。我想我需要某种类型的间谍,但因为 DateWithoutTimePipe 没有被注入,我不确定如何在我的测试中伪造 class。

我最初尝试了下面的方法,当然立即意识到间谍从未真正被使用过。

it('should decode dates', () => {
    const spy = jasmine.createSpyObj('DateWithoutTimePipe', ['transform'])
    const dates = {'contractStart': '2020-01-01', 'contractEnd': '2030-02-03'}
    const dto = ClientDTO.fromJson(dates)

    expect(dto).toBeInstanceOf(ClientDTO)
    expect(spy.transform).toHaveBeenCalledTimes(2)

    const all = spy.transform.calls.all()

    expect(all[0].args).toBe(['2020-01-01'])
    expect(all[1].args).toBe(['2030-02-03'])
})

您可以使用 spyOn(obj, methodName) 在现有对象上安装间谍。

例如

MyClass.ts:

import { ClientDTO } from './ClientDTO';
import { DateWithoutTimePipe } from './DateWithoutTimePipe';

export class MyClass {
  static fromJson(json: any): ClientDTO {
    const ret: ClientDTO = Object.assign(new ClientDTO(), json);

    const dp = new DateWithoutTimePipe();

    ret.contractStart = dp.transform(json.contractStart);
    ret.contractEnd = dp.transform(json.contractEnd);

    return ret;
  }
}

ClientDTO.ts

export class ClientDTO {
  public contractStart;
  public contractEnd;
}

DateWithoutTimePipe.ts:

export class DateWithoutTimePipe {
  public transform(data) {}
}

MyClass.test.ts:

import { MyClass } from './MyClass';
import { DateWithoutTimePipe } from './DateWithoutTimePipe';
import { ClientDTO } from './ClientDTO';

describe('62461783', () => {
  it('should pass', () => {
    const transformSpy = spyOn(DateWithoutTimePipe.prototype, 'transform').and.callFake((data) => {
      if (data === '2020-01-01') {
        return 'transformed 2020-01-01';
      }
      if (data === '2030-02-03') {
        return 'transformed 2030-02-03';
      }
    });
    const json = { contractStart: '2020-01-01', contractEnd: '2030-02-03' };
    const actual = MyClass.fromJson(json);
    const all = transformSpy.calls.all();
    expect(all[0].args).toEqual(['2020-01-01']);
    expect(all[1].args).toEqual(['2030-02-03']);
    expect(actual).toBeInstanceOf(ClientDTO);
    expect(transformSpy).toHaveBeenCalledTimes(2);
  });
});

单元测试结果:

Executing 1 defined specs...
Running in random order... (seed: 45771)

Test Suites & Specs:
(node:41885) ExperimentalWarning: The fs.promises API is experimental

1. 62461783
   ✔ should pass (6ms)

>> Done!


Summary:

  Passed
Suites:  1 of 1
Specs:   1 of 1
Expects: 4 (0 failures)
Finished in 0.028 seconds