How do I mock sub component in jasmine tests?
I have MyComponent
, which uses MyNavbarComponent
and MyToolbarComponent
import {Component} from 'angular2/core';
import {MyNavbarComponent} from './my-navbar.component';
import {MyToolbarComponent} from './my-toolbar.component';
@Component({
selector: 'my-app',
template: `
<my-toolbar></my-toolbar>
{{foo}}
<my-navbar></my-navbar>
`,
directives: [MyNavbarComponent, MyToolbarComponent]
})
export class MyComponent {}
When I test this component, I do not want to load and test those two sub components; MyNavbarComponent, MyToolbarComponent, so I want to mock it.
I know how to mock with services using provide(MyService, useClass(...))
, but I have no idea how to mock directives; components;
beforeEach(() => {
setBaseTestProviders(
TEST_BROWSER_PLATFORM_PROVIDERS,
TEST_BROWSER_APPLICATION_PROVIDERS
);
//TODO: want to mock unnecessary directives for this component test
// which are MyNavbarComponent and MyToolbarComponent
})
it('should bind to {{foo}}', injectAsync([TestComponentBuilder], (tcb) => {
return tcb.createAsync(MyComponent).then((fixture) => {
let DOM = fixture.nativeElement;
let myComponent = fixture.componentInstance;
myComponent.foo = 'FOO';
fixture.detectChanges();
expect(DOM.innerHTML).toMatch('FOO');
});
});
Here is my plunker example;
Thanks to Eric Martinez, I found this solution.
We can use
overrideDirective
function which is documented here, https://angular.io/docs/ts/latest/api/testing/TestComponentBuilder-class.htmlIt takes three prarmeters; 1. Component to implement 2. Child component to override 3. Mock component
Resolved solution is here at http://plnkr.co/edit/a71wxC?p=preview
This is the code example from the plunker
I put together a simple
MockComponent
module to help make this a little easier:It's available at https://www.npmjs.com/package/ng2-mock-component.
As requested, I'm posting another answer about how to mock sub components with
input
/output
:So Lets start by saying we have
TaskListComponent
that displays tasks, and refreshes whenever one of them is clicked:app-task
is a sub component with the[task]
input and the(click)
output.Ok great, now we want to write tests for my
TaskListComponent
and of course we don't want to test the realapp-task
component.so as @Klas suggested we can configure our
TestModule
with:We might not get any errors at either build or runtime, but we won't be able to test much other than the existence of the sub component.
So how can we mock sub components?
First we'll define a mock directive for our sub component (same selector):
Now we'll declare it in the testing module:
In our tests, we can now query for the directive, access its DebugElement's injector, and get our mock directive instance through it:
[This part should usually be in the
beforeEach
section, for cleaner code.]From here, the tests are a piece of cake :)
If you use
schemas: [CUSTOM_ELEMENTS_SCHEMA]
inTestBed
the component under test will not load sub components.This works in the released version of Angular 2.0. Full code sample here.
An alternative to
CUSTOM_ELEMENTS_SCHEMA
isNO_ERRORS_SCHEMA