Home > Software engineering >  How to mock readonly property in nodejs using jest
How to mock readonly property in nodejs using jest

Time:01-18

I have the following class which has a chunk defined as an array and multiple objects get pushed into this array this.chunk.

SearchController.ts

@Injectable()
export class SearchController {
  private chunk: any[] = [];
  readonly CHUNK_SIZE: number = 100;

  public async post(names) {

    this.chunk.push(names);

    if (this.chunk.length >= this.CHUNK_SIZE) {
        return true;
    }
    return false;

  }
}

I want to be able to either mock the CHUNK_SIZE to a number equal to 1 or maybe be able to change the value of the chunk.length

Below is my test

SearchController.test.ts

  it('should return true for chunk_size 1', async () => {

    const actual = await queue.post({action: 'UPDATE'});


    expect(actual).toBeTruthy();
  });

I have tried using jest.spyOn() but it didn't work. What am I missing?

Would really appreciate if anyone can help. thanks.

CodePudding user response:

You can use the following trick inside of it block:

Object.defineProperty(<instanceOfController>, 'CHUNK_SIZE', { value: <anyRandomValue>, writable: false });

For example:

it('should return true for chunk_size 1', async () => {
  Object.defineProperty(queue, 'CHUNK_SIZE', { value: 1, writable: false });

  const actual = await queue.post({ action: 'UPDATE' });
  expect(actual).toBeTruthy();
});

CodePudding user response:

My technique for such cases is to create a derived test-specific class:

class SearchControllerTest extends SearchController {
  override readonly CHUNK_SIZE = 1; // property cannot be private in parent class
}

… and then mock the SearchController.ts module with the new class. If necessary, I use jest.requireActual() to get the true value of the module.

  • Related