Angular version: 8.1.2
Testing tools: Karma and Jasmine, as pre-installed by ng new
I am currently working on my first ever Angular project. As a part of this, I have created a pipe which calls DomSanitizer.bypassSecurityTrustResourceUrl
. I do this in order to be able to use them in iframes. I now want to implement tests for this pipe. Here is the code for it:
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from "@angular/platform-browser";
@Pipe({
name: 'safe'
})
export class SafeResourceUrlPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) { }
transform(url: string): SafeResourceUrl | string {
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
}
The auto-generated spec file only looked like this:
import { TestBed, async } from '@angular/core/testing';
import { SafeResourceUrlPipe } from './safe-resource-url.pipe';
import { DomSanitizer } from '@angular/platform-browser';
describe('Pipe: SafeResourceUrle', () => {
it('should create an instance', () => {
let pipe = new SafeResourceUrlPipe();
expect(pipe).toBeTruthy();
});
});
That this wouldn't work VSCode told me before I even ran the tests, because SafeResourceUrlPipe
's constructor expects an argument. So far so good, but I don't know what to do now. I can't just use new DomSanitizer
, because it is an abstract class.
What I have tried is creating a mock class that implements DomSanitizer, but with that I can't do much more than testing whether the pipe is even created, and I knew that before already. What I would like to test is whether it properly does its job transforming inputs, but I can hardly test that when I'm pseudo-implementing the main dependency.
I have done some Googling about this and I suspect it will turn out to be something obvious, but I couldn't find it.
I'd recommend using the Angular Testbed to inject a mock of the dom sanitizer like this.
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SafeResourceUrlPipe],
providers: [
SafeResourceUrlPipe,
{ provide: DomSanitizer, useValue: {bypassSecurityTrustResourceUrl(){}}
]
});
}));
Then
describe('Pipe: SafeResourceUrle', () => {
it('should create an instance', () => {
let pipe = TestBed.get(SafeResourceUrlPipe);
expect(pipe).toBeTruthy();
});
});
p.s. the useValue
is important here. If you only provide a value here then its fine. If you want to replace that with a full mocked class you must useClass
(small slip up that most people get stuck on)
export class MockDomSanitizer {
bypassSecurityTrustResourceUrl() {}
otherMethods(){}
}
This should allow you to run the pipe with the mocked out dom sanitizer method.