【问题标题】:Mock object creation using jest使用 jest 创建模拟对象
【发布时间】:2021-07-28 10:25:47
【问题描述】:

我对开玩笑测试很陌生。我有下面的实现类

import { ExternalObject } from 'external-library';

export class MyClass {
  public createInstance(settings : ISettings) : ExternalObject {
    const setting1 = settings.getSetting("setting1");
    const setting2 = settings.getSetting("setting2");
    return new ExternalObject(setting1, setting2);
  }
}

我正在尝试测试这个类,我已经能够正确地模拟设置。但是我无法模拟外部对象构造 new ExternalObject(setting1, setting2); 并且我的测试用例失败,因为它试图构造实际对象(由于传递的参数不是实际的有效值而失败)。

describe("Create Instance", () => {  
  test("Allow creation of external instance", () => {
    // not sure if I am using this correctly? 
    // Aim is to mock out external module and any objects it may need creating
    jest.mock('external-library', () => {
      return {
        ExternalObject: jest.fn().mockImplementation()
      }
    });
    let settings: ISetting = new Settings();
    jest.spyOn(settings, "getSetting")
    .mockImplementationOnce(() => 'abcd')
    .mockImplementationOnce(() => 'xyz')

    let myImpl = new MyClass();
    let inst = myImpl.createInstance(settings);
    // expecting that the instance is created successfully.
    expect(inst).toBeTruthy();
  });
});

但是我不确定我在这里做错了什么。我确实浏览了文档和其他一些问题,但无法理解我错过了什么。

【问题讨论】:

    标签: typescript unit-testing jestjs ts-jest


    【解决方案1】:

    在函数范围内使用jest.mock(),模拟模块不会被提升到代码块的顶部。这将导致external-library 模块在导入正在测试的代码时不会被模拟。只需将jest.mock() 移动到测试文件的模块范围即可。

    例如

    MyClass.ts:

    //@ts-ignore
    import { ExternalObject } from 'external-library';
    import { ISettings } from './Settings';
    
    export class MyClass {
      public createInstance(settings: ISettings): ExternalObject {
        const setting1 = settings.getSetting('setting1');
        const setting2 = settings.getSetting('setting2');
        return new ExternalObject(setting1, setting2);
      }
    }
    

    Settings.ts:

    export interface ISettings {
      getSetting(key: string): void;
    }
    
    export class Settings implements ISettings {
      getSetting(key: string) {
        return 'real implementation';
      }
    }
    

    MyClass.test.ts:

    import { MyClass } from './MyClass';
    import { ISettings, Settings } from './Settings';
    //@ts-ignore
    import { ExternalObject } from 'external-library';
    
    jest.mock(
      'external-library',
      () => {
        return { ExternalObject: jest.fn() };
      },
      { virtual: true }
    );
    
    describe('68545423', () => {
      afterEach(() => {
        jest.restoreAllMocks();
      });
      afterAll(() => {
        jest.resetAllMocks();
      });
      test('should pass', () => {
        let myImpl = new MyClass();
        let settings: ISettings = new Settings();
        jest
          .spyOn(settings, 'getSetting')
          .mockImplementationOnce(() => 'abcd')
          .mockImplementationOnce(() => 'xyz');
    
        let inst = myImpl.createInstance(settings);
        expect(inst).toBeTruthy();
        expect(ExternalObject).toBeCalledWith('abcd', 'xyz');
      });
    });
    

    测试结果:

     PASS  examples/68545423/MyClass.test.ts (7.233 s)
      68545423
        ✓ should pass (4 ms)
    
    -------------|---------|----------|---------|---------|-------------------
    File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    -------------|---------|----------|---------|---------|-------------------
    All files    |   85.71 |      100 |      50 |   85.71 |                   
     MyClass.ts  |     100 |      100 |     100 |     100 |                   
     Settings.ts |      50 |      100 |       0 |      50 | 7                 
    -------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        8.032 s, estimated 9 s
    Ran all test suites related to changed files.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      • 2019-10-10
      • 2017-04-07
      • 2019-10-13
      相关资源
      最近更新 更多