Skip to main content

Mocking DomSanitizer

This article explains how to mock DomSanitizer in Angular tests properly.

The biggest issue is that DomSanitizer are used internally by Angular. Therefore, mocking them can cause unpredictable errors such as:

  • TypeError: view.root.sanitizer.sanitize is not a function
  • TypeError: _co.domSanitizer.bypassSecurityTrustHtml is not a function

Because of that ng-mocks avoids its mocking by default.

Another problem is that the class is abstract and there is no way to detect their abstract methods in javascript runtime in order to provide mock functions or spies instead.

However, ng-mocks contains MockRender which supports additional providers for rendered things. Therefore, if we use MockRender and MockProvider, we can achieve desired environment and behavior:

// rendering TargetComponent componentMockRender(TargetComponent, null, {  // providing special overrides for TargetComponent  providers: [    // Mocking DomSanitizer with a fake method    MockProvider(DomSanitizer, {      // the override should be provided explicitly      // because sanitize method is abstract      sanitize: jasmine.createSpy('sanitize'),    }),  ],});

Profit.

Always mock / spy DomSanitizer#

If you want to spy DomSanitizer globally, you can use ngMocks.globalMock and ngMocks.defaultMock.

In this case, ng-mocks understands that DomSanitizer should be mocked by default.

The only concern is that Angular uses DomSanitizer internally. Therefore, its mock methods should the passed value at least.

// Let ng-mocks know that it should be mockedngMocks.globalMock(DomSanitizer);
// Let ng-mocks know how the mock should be definedngMocks.defaultMock(DomSanitizer, sanitizer => {    // Jasmine example  sanitizer.sanitize = jasmine.createSpy().and.callFake(v => v);  // all other methods
    // Jest example  sanitizer.bypassSecurityTrustHtml = jest.fn(v => v);  // all other methods
    return sanitizer;});

Full example#

A full example of mocking DomSanitizer in Angular tests.

describe('MockSanitizer', () => {  beforeEach(() => MockBuilder(TargetComponent));
  it('renders expected mock values', () => {    MockRender(TargetComponent, null, {      providers: [        MockProvider(DomSanitizer, {          sanitize: (context: SecurityContext, value: string) =>            `sanitized:${context}:${value.length}`,        }),      ],    });
    expect(ngMocks.formatHtml(ngMocks.find('div')))      .toEqual('sanitized:1:23');  });});