Jest.js 在每个单元测试中重置typescript单例示例

ruyhziif  于 12个月前  发布在  Jest
关注(0)|答案(3)|浏览(126)

我有一个这样的单例类:

export default class MySingleton {
private constructor({
    prop1,
    prop2,
    ...
  }: MySingletonConfig) {
    
    this.prop1 = prop1 ?? 'defaultProp1';
    this.prop2 = prop2;
    this.prop3 = prop3 ?? 'defaultProp3';

    /* ... some instruction ... */

    MySingleton.instance = this;
  }

  static getInstance(params?: Configuration): MySingleton {
    if (!this.instance && !params) {
      throw MySingleton.instantiationError;
    }

    if (!this.instance) {
      new MySingleton(params);

      return this.instance;
    }

    return this.instance;
  }
}

当我想使用jest进行单元测试时,像这样:

describe('getInstance()', () => {
    test('it should return the same instance every time', () => {
      const params = {
       /* ... all the params ... */
      };

     
      const mySingleton = MySingleton.getInstance(params);

      expect(MySingleton.getInstance()).toEqual(mySingleton);
    });
    test('it should return the instance with the default value', () => {
      const params = {
       /* ... ONLY THE REQUIRED PARAMS ... */
      };
     
      const mySingleton = MySingleton.getInstance(params);

      expect(mySingleton.prop1).toEqual('defaultProp1');
      expect(mySingleton.prop3).toEqual('defaultProp3');
    });
  });

这是失败的,因为我们在两个测试之间共享相同的示例(因为单例模式工作),因此第二个示例化是无用的。
是否有办法重置/销毁前一个示例化,以便正确检查这些默认值是否与第二个示例化正确设置?

mqxuamgl

mqxuamgl1#

理想情况下,istance属性应该是really private,但没有人阻止您在类中添加reset()方法。它不是特别整洁,因为它基本上只是用于测试目的,但至少它更接近单例模式的规范实现。
话虽如此,我会仔细考虑使用单例是否是一个好主意。在对代码进行单元测试时,它可能会带来很多麻烦。基本上,当您尝试测试一些使用单例的代码时,您在这里遇到的相同问题可能会在其他地方出现。

9rygscc1

9rygscc12#

我不明白你为什么不能做:

MySingleton.instance = null;
const mySingleton = MySingleton.getInstance(params);
fkvaft9z

fkvaft9z3#

我已经创建了一个单例类,使用了以下重置方法,并且它可以正常工作:

import { Injectable } from '@nestjs/common';

@Injectable()
export class SingletonDemo {
  private static _instance: SingletonDemo;

  public static getInstance() {
    return this._instance || (this._instance = new this());
  }

  public static resetInstance() {
    this._instance = null;
  }

}

相关问题