Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript unit test private and protected methods

I want to be able to test private Typescript methods. Please skip your lecture of why this is a bad idea. I've heard it.

Here is a demo code:

class MyClass {
    age: number

    private ageAsString(): string {
        return '15'
    }
}

Here are my options in the test file:

1 - Write //@ts-ignore which allows TS to compile this line. This gets inconvenient very quickly when you're calling 200 x expect()s. But I couldn't find a way to do this block based of file based.

it('Test ageAsString', () => {
    // @ts-ignore
    expect(new MyClass().ageAsString()).to.equal('15')
})

2 - Turning a class object to any object. This disables autocomplete and refactoring features I get from TS and my IDE. It seems like a good idea at first but 1 month later it will either break 200 of my test cases or create some unforeseen bugs.

it('Test ageAsString', () => {
    const anyClass: any = new MyClass
    expect(anyClass.ageAsString()).to.equal('15')
})

3 - Can use array access, which works but creates the same problems as #2.

it('Test ageAsString', () => {
    expect(new MyClass()['ageAsString']()).to.equal('15')
})

I want to somehow be able to test these methods without having the downsides. Right now I have 2 choices, both are bad.

  1. Skip writing specific detailed unit tests
  2. Make method public

Please give me a 3rd option

like image 318
Esqarrouth Avatar asked Feb 23 '19 20:02

Esqarrouth


1 Answers

One other way of testing protected methods is to create a Fake class and extend your class that needs to be tested.

class MyClass {
  protected test() {
    return true;
  }
}
class FakeMyClass extends MyClass {
  public test() {
    return super.test();
  }
}
it('test', () => {
    const myClass = new FakeMyClass();
    expect(myClass.test()).to.true;
})
like image 90
harshaaliaschinna Avatar answered Oct 16 '22 04:10

harshaaliaschinna