Search code examples
javascriptunit-testingtestingjestjsag-grid

How to unit test logic under AG GRID gridApi function forEachNode


Trying to get my unit test coverage for this bit of code:

  processUpdates(input) {
    let request = [];
    this.gridApi.forEachNode(function (node) { // <--- How to mock/spy inside forEachNode
      if (input.has(data.id)) {
        request.push(this.createRequestRowUpdate(node, input));
      }
      this.someCoolService.saveMychanges(request).pipe(map(res => res as any)).subscribe(res => {
        //success 
      }, (error: HttpErrorResponse) => {
        //failure
      });
    });
  }

How can I set my test up so I can make some assertions on some of the code inside the forEachNode call on the gridApi?

example

expect(service['saveMychanges']).toHaveBeenCalledOnce();

Reference

https://www.ag-grid.com/javascript-data-grid/grid-api/#reference-rowNodes-forEachNode

Stack and Versions Angular 15

"jest": "^29.5.0"

"ag-grid-angular": "^25.3.0",

UPDATE

Forgot to show in my question how I was mocking my grid api

const mGridApi = {
  sizeColumnsToFit: function () {
  },
  setRowData: function () {
  },
  updateRowData: function () {
  },
  setFocusedCell: function () {
  },
  startEditingCell: function () {
  },
  showNoRowsOverlay: function () {
  },
  hideOverlay: function () {
  },
  refreshCells: function () {
  },
  setColumnDefs: function () {
  },
  getSelectedRows: function () {
    return [{ // some object definition }];
  },
  stopEditing: function () {
  },
  exportDataAsCsv: function () {
  },
  forEachNode: function () { // I'm guessing I have to give it some sort of mock here so that I can read under the call?
  },
  setSortModel: function () {
  }
};

Test

it('should call processUpdate', async () => {
   component['gridApi'] = mGridApi;
   jest.spyOn(component, 'processUpdate');
   jest.spyOn(component, 'createRequestRowUpdate');
   jest.spyOn(service, 'saveMychanges');

   component['processUpdate']('test data in here');
   expect(component['createRequestRowUpdate']).hasBeenCalledOnce()

Hope that helps explain the issue better


Solution

  • Turns out all I needed to do was to give the mock an implementation of the method. Took a minute to wrap my head around how to do it but this is what I came up with,

    In a beforeEach or the setup section of the test provide this implementation to the gridApi object

        component['gridApi']['forEachNode'] = jest.fn((callback) => {
          const mockNodes = [{ data: { id: 1, value: 'cheers-luv'}}]
          mockNodes.forEach(node => callback(node));
        })
    

    You can supply more data object if you'd like the implementation to iterate more than once.