How to mock pipes in Angular tests
A mock pipe in Angular tests can be created by MockPipe function.
The second parameter of the function accepts a custom transform callback.
The mock pipe has the identical interface as its source pipe,
but all its methods are dummies.
To provide a mock pipe in a test, pass this source pipe into MockPipe function.
TestBed.configureTestingModule({
declarations: [
// for a single pipe
MockPipe(Pipe),
// a fake transform callback
MockPipe(Pipe, value => JSON.stringify(value)),
// for a set of pipe
...MockPipes(Pipe1, Pipe2),
],
});
A mock pipe has:
- the same
name - default transform is
() => undefinedto prevent problems with chaining
Simple example
Let's imagine that in an Angular application TargetComponent depends on DependencyPipe pipe,
and we would like to replace it with its mock pipe.
Usually a test looks like:
describe('Test', () => {
let component: TargetComponent;
let fixture: ComponentFixture<TargetComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
// our component for testing
TargetComponent,
// the annoying dependency
DependencyPipe,
],
});
fixture = TestBed.createComponent(TargetComponent);
component = fixture.componentInstance;
});
});
To create a mock pipe out of a pipe, simply pass the original pipe into MockPipe:
TestBed.configureTestingModule({
declarations: [
TargetComponent,
// profit
MockPipe(DependencyPipe, value => `mock:${value}`),
],
});
Or if we want to be like a pro, use MockBuilder, its .mock method
and call MockRender:
describe('Test', () => {
beforeEach(() => {
return MockBuilder(TargetComponent)
.mock(DependencyPipe, value => `mock:${value}`);
});
it('should create', () => {
const fixture = MockRender(TargetComponent);
expect(fixture.point.componentInstance).toBeDefined();
expect(fixture.nativeElement.innerHTML).toContain('mock:foo');
// An instance of DependencyPipe from the fixture if we need it.
const pipe = ngMocks.findInstance(DependencyPipe);
expect(pipe).toBeDefined();
});
});
Advanced example
An advanced example of mocking pipes in Angular tests. Please, pay attention to comments in the code.
// A fake transform function.
const fakeTransform = (...args: string[]) => JSON.stringify(args);
describe('MockPipe', () => {
// A spy, just in case if we want to verify
// how the pipe has been called.
const spy = jasmine.createSpy().and.callFake(fakeTransform);
// in case of jest
// const spy = jest.fn().mockImplementation(fakeTransform);
beforeEach(() => {
return MockBuilder(TargetComponent, TargetModule).mock(
DependencyPipe,
spy,
);
});
it('transforms values to json', () => {
const fixture = MockRender(TargetComponent);
expect(fixture.nativeElement.innerHTML).toEqual(
'<component>["foo"]</component>',
);
// Also we can find an instance of the pipe in
// the fixture if it is needed.
const pipe = ngMocks.findInstance(DependencyPipe);
expect(pipe.transform).toHaveBeenCalledWith('foo');
expect(pipe.transform).toHaveBeenCalledTimes(1);
});
});