angularjestjsmockingngx-quill

ngx-quill tests fail when using Angular 10.2 with Jest after upgrade


Upgrading from Angular 9.x to Angular 10.x all the specs of components using the component quill-editor from ngx-quill fail to load.

This is produced by the standard angular test:

    it('should create', () => {
        expect(component).toBeTruthy();
    });

This is the error message they produce:

 FAIL   my-project  src/(...)/my-component.spec.ts
  ● Test suite failed to run

    Call retries were exceeded

      at ChildProcessWorker.initialize (node_modules/jest-worker/build/workers/ChildProcessWorker.js:193:21)

This happens whilst our views have a simple quill editor usage:

<quill-editor formControlName="myControlName"></quill-editor>

(commenting or removing this line allows the tests to pass)

Previouslly mocking the module quill with a jest.mock call was enough:

jest.mock('quill');

but now the tests just fail...

we load the QuillModule in a shared component and import this shared component as required:

@NgModule({
    declarations: [],
    imports: [
        QuillModule.forRoot({
            modules: {
                toolbar: [
                    ['bold', 'italic', 'underline', 'strike'],
                ],
            },
        }),
    ],
    exports: [QuillModule],
})
export class QuillEditorModule {}

Solution

  • We ended up mocking the module QuillEditorModule with jest in all spec files using our wrapper module:

    Making sure this comes at the top of the ..spec.ts file we were able to stub the ngx-quill module and its used component selector "quill-editor", and all the tests passed again:

    import { QuillEditorModuleStub } from 'src/(my-app-paths)/quill-editor.module.stub';
    
    jest.mock(`src/(my-app-paths)/quill-editor.module`, () => ({
        __esModule: true,
        QuillEditorModule: QuillEditorModuleStub,
    }));
    

    Stub Component

    import { Component, forwardRef } from '@angular/core';
    import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
    
    @Component({
        selector: 'quill-editor',
        template: '',
        providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => QuillEditorComponentStub),
                multi: true,
            },
        ],
    })
    export class QuillEditorComponentStub implements ControlValueAccessor {
        registerOnChange(fn: any): void {}
    
        registerOnTouched(fn: any): void {}
    
        writeValue(obj: any): void {}
    }
    

    Stub Module:

    import { NgModule } from '@angular/core';
    import { QuillEditorComponentStub } from './quill-editor-component.stub';
    
    @NgModule({
        declarations: [QuillEditorComponentStub],
        exports: [QuillEditorComponentStub],
    })
    export class QuillEditorModuleStub {}