Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

testing private functions in typescript with jest

In the below code my test case was passed as expected but i am using stryker for mutation testing , handleError function is survived in mutation testing , so i want to kill the mutant by testing the handleError function is being called or not. need to help to test the private function.

i tried spyOn but didn't work

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)
    }
  });
});
like image 771
sravan ganji Avatar asked May 08 '19 15:05

sravan ganji


People also ask

Can you write jest tests in TypeScript?

Via ts-jest ​ts-jest is a TypeScript preprocessor with source map support for Jest that lets you use Jest to test projects written in TypeScript.

How do I test a TypeScript function?

For TypeScript, unit tests are run against the generated JavaScript code. In most TypeScript scenarios, you can debug a unit test by setting a breakpoint in TypeScript code, right-clicking a test in Test Explorer, and choosing Debug.

Can you test a private function?

The short answer is that you shouldn't test private methods directly, but only their effects on the public methods that call them. Unit tests are clients of the object under test, much like the other classes in the code that are dependent on the object.

Can we test private methods in unit testing angular?

But since you are unit testing an instance of an Angular component, you won't be able to access the private method.


1 Answers

It looks like you are wanting to verify that handleError gets called when build runs.

Private methods are compiled to normal JavaScript prototype methods, so you can use the any type to let the spy creation pass through the TypeScript type checking.

Here is a highly simplified example:

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!
  });
});
like image 193
Brian Adams Avatar answered Oct 23 '22 01:10

Brian Adams