用玩笑测试打字稿中的私有函数

Posted

技术标签:

【中文标题】用玩笑测试打字稿中的私有函数【英文标题】:testing private functions in typescript with jest 【发布时间】:2019-09-26 09:46:50 【问题描述】:

在下面的代码中,我的测试用例按预期通过了,但我使用 stryker 进行突变测试,handleError 函数在突变测试中幸存下来,所以我想通过测试是否调用了 handleError 函数来杀死突变体。需要帮忙测试一下私有函数。

我试过 spyOn 但没用

const orderBuilderSpy = jest.spyOn(orderBuilder, 'build')
const handleError = jest.fn()
expect(rderBuilderSpy).toHaveBeenCalledWith(handleError)

// code written in nestJS/typescript

export class OrderBuilder 
  private amount: number

  public withAmount(amount: number): BuyOrderBuilder 
    this.amount = amount
    return this
  


  public build(): TransactionRequest 
    this.handleError()
    return 
      amount: this.amount,
      acceptedWarningRules: [
        
          ruleNumber: 4464
        
      ]
    
  
  private handleError() 
    const errors: string[] = []
    const dynamicFields: string[] = [
      'amount',
    ]
    dynamicFields.forEach((field: string) => 
      if (!this[field]) 
        errors.push(field)
      
    )
    if (errors.length > 0) 
      const errorMessage = errors.join()
      throw new Error(`missing $errorMessage field in order`)
    
  




// test
describe('Order Builder', () => 
  it('should test the handleError', () => 
    const orderBuilder = new OrderBuilder()
    const errorMessage = new Error(
      `missing amount field in order`
    )
    try 
      orderBuilder.build()
     catch (error) 
      expect(error).toEqual(errorMessage)
    
  );
);

【问题讨论】:

【参考方案1】:

您似乎想要验证 handleError 是否在 build 运行时被调用。

私有方法被编译成普通的 javascript 原型方法,所以你可以使用 any 类型让 spy 创建通过 TypeScript 类型检查。

这是一个高度简化的例子:

class OrderBuilder 
  public build() 
    this.handleError()
  
  private handleError() 
    throw new Error('missing ... field in order')
  


describe('Order Builder', () => 
  it('should test the handleError', () => 
    const handleErrorSpy = jest.spyOn(OrderBuilder.prototype as any, 'handleError');
    const orderBuilder = new OrderBuilder()
    expect(() => orderBuilder.build()).toThrow('missing ... field in order');  // Success!
    expect(handleErrorSpy).toHaveBeenCalled();  // Success!
  );
);

【讨论】:

这是一个非常好的模拟 javascript 类中的私有方法的例子。我一直在尝试不同的方式 jest.fn(), jest.spyOn() 但不能让它更早地工作。但现在我知道了。 如果handleError 是箭头函数并因此是对象的属性,有没有办法做到这一点?

以上是关于用玩笑测试打字稿中的私有函数的主要内容,如果未能解决你的问题,请参考以下文章

我们可以在打字稿中访问另一个类中的私有变量吗

我们可以在打字稿中访问另一个类中的私有变量吗

打字稿中的多个构造函数

打字稿中的重载函数类型

如何在打字稿中声明函数类型

获取泛型函数的类型而不调用打字稿中的函数