I have a modal which is opened as soon as the user selects the menu option for the page. Isue i'm having is that i have no idea on how to get it to call my function call in my ngOnInit
test.component.ts
constructor(public dialog: MdDialog) { }
ngOnInit() {
this.openTestModal();
}
openTestModal() {
this.dialog.open(TestModalComponent, {
disableClose: true,
width: '600px'
});
}
I have imported my model component and tried:
change-password.component.spec.ts
import { TestModalComponent } from '../test-modal/test-modal.component';
spyOn(component, 'openTestModal');
spyOn(component, 'ngOnInit').and.callThrough();
it('should be created', () => {
expect(component).toBeTruthy();
});
Error
No component factory found for TestComponent. Did you add it to
#NgModule.entryComponents?
but its already in there
To solve this add your TestComponent to a module at end of your test with entryComponents.
#NgModule({
declarations: [TestComponent],
entryComponents: [
TestComponent,
],
})
class TestModule {}
and add TestModule to the testBed imports.
Related
I am learning to write unit tests in ionic and am unable to write a test for AlertController. Below attached is the code
Terms.page.ts file
export class TermsPage {
constructor(private router: Router, private alertController: AlertController) {}
onAgreeClick() {
this.router.navigate(['/register']);
}
onDeclineClick() {
this.presentAlertConfirm();
}
async presentAlertConfirm() {
const alert = await this.alertController.create({
message: 'Please agree to our terms and conditions to be able to use this application!',
buttons: [
{
text: 'Agree',
cssClass: 'primary',
handler: () => {
this.onAgreeClick();
},
},
{
text: 'Maybe later',
role: 'cancel',
cssClass: 'secondry',
},
],
});
await alert.present();
}
}
Terms.spec.ts
import { DebugElement } from '#angular/core';
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { Router, RouterModule } from '#angular/router';
import { RouterTestingModule } from '#angular/router/testing';
import { EmptyTestComponent } from '#test-utils';
import { TermsPage } from './terms.page';
fdescribe('TermsConditionsComponent', () => {
let component: TermsPage;
let fixture: ComponentFixture<TermsPage>;
let de: DebugElement;
let router: Router;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TermsPage],
imports: [
RouterModule.forRoot([]),
RouterTestingModule.withRoutes([{ path: '**', component: EmptyTestComponent }]),
],
}).compileComponents();
fixture = TestBed.createComponent(TermsPage);
component = fixture.componentInstance;
de = fixture.debugElement;
router = TestBed.inject(Router);
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
it('should be able to agree and go to registration on click', async () => {
const agreeButton = de.query(By.css('#button-agree')).nativeElement as HTMLIonButtonElement;
agreeButton.click();
await fixture.whenStable();
expect(router.url).toBe('/register');
});
it('should be able to trigger popup on click of disagree click', async () => {
const disagreeButton = de.query(By.css('#button-disagree')).nativeElement as HTMLIonButtonElement;
disagreeButton.click();
await fixture.whenStable();
expect(component.presentAlertConfirm).toBeTruthy();
});
});
I need to hit the 100% coverage
Would really appreciate it if someone could help me write test case to cover the alert button actions and present. Thanks in advance
Looks like you need to split your test into two:
test #1 for alertcontroller.create usage - to has been called with proper arguments
and test #2 for button handlers
First can be easely emulated with standard jasmine calls like .toHaveBeenCalledWith(...):
const alertControllerStub = jasmine.createSpyObj('AlertController', ['create']);
...
expect(alertControllerStub.create).toHaveBeenCalledWith(options);
And the second one, you need to fire "ok"/"cancel" manually and catch the method executed for both cases
const ({buttons}) = alertControllerStub.create.calls.first().args[0];
buttons[0].handler();
expect(smth_should_called_in_handler).toHaveBeenCalled();
I'm creating a unit test for my Navbar Component and I'm getting an error:
Can't bind to 'routerLink' since it isn't a known property of 'a'
Navbar Component TS
import { Component } from '#angular/core';
import { Router } from '#angular/router';
import { NavActiveService } from '../../../services/navactive.service';
import { GlobalEventsManager } from '../../../services/GlobalEventsManager';
#Component({
moduleId: module.id,
selector: 'my-navbar',
templateUrl: 'navbar.component.html',
styleUrls:['navbar.component.css'],
providers: [NavActiveService]
})
export class NavComponent {
showNavBar: boolean = true;
constructor(private router: Router,
private navactiveservice:NavActiveService,
private globalEventsManager: GlobalEventsManager){
this.globalEventsManager.showNavBar.subscribe((mode:boolean)=>{
this.showNavBar = mode;
});
}
}
Navbar Component Spec
import { ComponentFixture, TestBed, async } from '#angular/core/testing';
import { NavComponent } from './navbar.component';
import { DebugElement } from '#angular/core';
import { By } from '#angular/platform-browser';
import { Router } from '#angular/router';
export function main() {
describe('Navbar component', () => {
let de: DebugElement;
let comp: NavComponent;
let fixture: ComponentFixture<NavComponent>;
let router: Router;
// preparing module for testing
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [NavComponent],
}).compileComponents().then(() => {
fixture = TestBed.createComponent(NavComponent);
comp = fixture.componentInstance;
de = fixture.debugElement.query(By.css('p'));
});
}));
it('should create component', () => expect(comp).toBeDefined());
/* it('should have expected <p> text', () => {
fixture.detectChanges();
const h1 = de.nativeElement;
expect(h1.innerText).toMatch(" ");
});*/
});
}
I realize that I need to add router as a spy, but if I add it as a SpyObj and declare it as a provider I get the same error.
Is there a better way for me to add fix this error?
EDIT: Working Unit Test
Built this unit test based on the answer:
import { ComponentFixture, TestBed, async } from '#angular/core/testing';
import { NavComponent } from './navbar.component';
import { DebugElement } from '#angular/core';
import { By } from '#angular/platform-browser';
import { RouterLinkStubDirective, RouterOutletStubComponent } from '../../../../test/router-stubs';
import { Router } from '#angular/router';
import { GlobalEventsManager } from '../../../services/GlobalEventsManager';
import { RouterModule } from '#angular/router';
import { SharedModule } from '../shared.module';
export function main() {
let comp: NavComponent;
let fixture: ComponentFixture<NavComponent>;
let mockRouter:any;
class MockRouter {
//noinspection TypeScriptUnresolvedFunction
navigate = jasmine.createSpy('navigate');
}
describe('Navbar Componenet', () => {
beforeEach( async(() => {
mockRouter = new MockRouter();
TestBed.configureTestingModule({
imports: [ SharedModule ]
})
// Get rid of app's Router configuration otherwise many failures.
// Doing so removes Router declarations; add the Router stubs
.overrideModule(SharedModule, {
remove: {
imports: [ RouterModule ],
},
add: {
declarations: [ RouterLinkStubDirective, RouterOutletStubComponent ],
providers: [ { provide: Router, useValue: mockRouter }, GlobalEventsManager ],
}
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(NavComponent);
comp = fixture.componentInstance;
});
}));
tests();
});
function tests() {
let links: RouterLinkStubDirective[];
let linkDes: DebugElement[];
beforeEach(() => {
// trigger initial data binding
fixture.detectChanges();
// find DebugElements with an attached RouterLinkStubDirective
linkDes = fixture.debugElement
.queryAll(By.directive(RouterLinkStubDirective));
// get the attached link directive instances using the DebugElement injectors
links = linkDes
.map(de => de.injector.get(RouterLinkStubDirective) as RouterLinkStubDirective);
});
it('can instantiate it', () => {
expect(comp).not.toBeNull();
});
it('can get RouterLinks from template', () => {
expect(links.length).toBe(5, 'should have 5 links');
expect(links[0].linkParams).toBe( '/', '1st link should go to Home');
expect(links[1].linkParams).toBe('/', '2nd link should go to Home');
expect(links[2].linkParams).toBe('/upload', '3rd link should go to Upload');
expect(links[3].linkParams).toBe('/about', '4th link should to to About');
expect(links[4].linkParams).toBe('/login', '5th link should go to Logout');
});
it('can click Home link in template', () => {
const uploadLinkDe = linkDes[1];
const uploadLink = links[1];
expect(uploadLink.navigatedTo).toBeNull('link should not have navigated yet');
uploadLinkDe.triggerEventHandler('click', null);
fixture.detectChanges();
expect(uploadLink.navigatedTo).toBe('/');
});
it('can click upload link in template', () => {
const uploadLinkDe = linkDes[2];
const uploadLink = links[2];
expect(uploadLink.navigatedTo).toBeNull('link should not have navigated yet');
uploadLinkDe.triggerEventHandler('click', null);
fixture.detectChanges();
expect(uploadLink.navigatedTo).toBe('/upload');
});
it('can click about link in template', () => {
const uploadLinkDe = linkDes[3];
const uploadLink = links[3];
expect(uploadLink.navigatedTo).toBeNull('link should not have navigated yet');
uploadLinkDe.triggerEventHandler('click', null);
fixture.detectChanges();
expect(uploadLink.navigatedTo).toBe('/about');
});
it('can click logout link in template', () => {
const uploadLinkDe = linkDes[4];
const uploadLink = links[4];
expect(uploadLink.navigatedTo).toBeNull('link should not have navigated yet');
uploadLinkDe.triggerEventHandler('click', null);
fixture.detectChanges();
expect(uploadLink.navigatedTo).toBe('/login');
});
}
}
Just import RouterTestingModule in TestBed.configureTestingModule of your components spec.ts file
Eg:
import { RouterTestingModule } from '#angular/router/testing';
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [ ComponentHeaderComponent ]
})
The Angular Testing docs address this by using RouterLinkDirectiveStub and RouterOutletStubComponent so that routerLink is a known property of <a>.
Basically it says that using RouterOutletStubComponent is a safe way to test routerLinks without all the complications and errors of using the real RouterOutlet. Your project needs to know it exists so it doesn't throw errors but it doesn't need to actually do anything in this case.
The RouterLinkDirectiveStub enables you to click on <a> links with routerLink directive and get just enough information to test that it is being clicked (navigatedTo) and going to the correct route (linkParams). Any more functionality than that and you really aren't testing your component in isolation any more.
Take a look at their Tests Demo in app/app.component.spec.ts. Grab the testing/router-link-directive-stub.ts and add to your project. Then you will inject the 2 stubbed items into your TestBed declarations.
If you want only isolated test and DO NOT CARE about template,you can add NO_ERRORS_SCHEMA. This tells Angular not to show error if it encounters any unknown attribute or element in HTML
Eg:
TestBed.configureTestingModule({
declarations: [ ComponentHeaderComponent ],
schemas: [ NO_ERRORS_SCHEMA ]
})
Simply running the application I get no error and it works just fine, but when I run my tests I get the following error:
'pattern-list' is not a known element:
1. If 'pattern-list' is an Angular component, then verify that it is part of this module.
2. If 'pattern-list' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '#NgModule.schema' of this component to suppress this message. ("
[ERROR ->]<pattern-list></pattern-list>
I had this issue first when I just run the application with 'npm-start' and I solved it adding the required component to app.module in the declarations section. But now as I want to test I get the same error and I don't know why.
Here is my code:
app.module.ts
#NgModule({
imports: [ BrowserModule, FormsModule, HttpModule, ReactiveFormsModule ],
declarations: [ AppComponent, PatternListComponent, PatternDetailComponent, WidgetListComponent,
FormComponent, DefaultWidget, LabelComponent, CheckboxWidget ],
bootstrap: [ AppComponent ],
providers: [ WidgetService ]
})
export class AppModule { }
app.component.ts
#Component({
selector: 'my-app',
template: `
<pattern-list></pattern-list>
`
})
export class AppComponent { }
pattern.list.component:
#Component({
selector: 'pattern-list',
template: `
<div class="patterns">
<pattern-detail *ngFor="let p of patternDetails" [metadata]="p"
(selectPattern)="selectPattern(p)"></pattern-detail>
</div>
<div *ngIf="selectedPattern" class="widget-list">
<widget-list [pattern]="selectedPattern">
</widget-list>
</div>
`,
styleUrls: ['/css/styles.css']
})
export class PatternListComponent implements OnInit{
selectedPattern: PatternDetails;
constructor(private http: Http) {
}
patternDetails: PatternDetails[];
ngOnInit() {
this.getPatterns();
}
getPatterns() {
this.http.get('/app/assets/patternDetails.json')
.map((res:Response) => res.json() )
.subscribe(
data => { this.patternDetails = data.patternList; },
err => console.error('The problem is: ' + err),
() => console.log('done')
);
console.log(this.patternDetails);
}
selectPattern(pattern: PatternDetails) {
this.selectedPattern = pattern;
this.setSelectedProperty(pattern);
}
setSelectedProperty(selectedPattern: PatternDetails) {
for (var p in this.patternDetails) {
if (this.patternDetails[p] == selectedPattern) {
this.patternDetails[p].selected = true;
} else {
this.patternDetails[p].selected = false;
}
}
}
}
My test file: app.component.spec.ts
describe('AppComponent with TCB', function () {
beforeEach(() => {
TestBed.configureTestingModule({declarations: [AppComponent]});
});
describe('asdfasdf', function () {
beforeEach(async(() => {
TestBed.compileComponents();
}));
it('should instantiate component', () => {
let fixture = TestBed.createComponent(AppComponent);
expect(fixture.componentInstance instanceof AppComponent).toBe(true, 'should create AppComponent');
});
});
});
I'm using webpack, I'm not sure if that matters.
I think you need
TestBed.configureTestingModule({imports: [AppModule]});
The current approach to avoid these errors when testing components is to make their tests shallow. As per the official docs:
Add NO_ERRORS_SCHEMA to the testing module's schemas metadata to tell the compiler to ignore unrecognized elements and attributes. You no longer have to declare irrelevant components and directives.
So you can simply import NO_ERRORS_SCHEMA and add it to your testing module config:
import { NO_ERRORS_SCHEMA } from '#angular/core';
TestBed.configureTestingModule({
schemas: [ NO_ERRORS_SCHEMA ]
})
But be aware of:
Shallow component tests with NO_ERRORS_SCHEMA greatly simplify unit testing of complex templates. However, the compiler no longer alerts you to mistakes such as misspelled or misused components and directives.
As micronyks mentined in his answer I need to add my other dependencies in the declarations of configureTestingModule. So if I modify my module configuration in the test like this:
TestBed.configureTestingModule({declarations: [AppComponent,PatternListComponent]});
it'll work. It seems you need to add every dependency in the configureTestingModule declaration.
I can't seem to test a component that uses a Date pipe in Angular 2 (using Karma through PhantomJS). When I try, I get ORIGINAL EXCEPTION: ReferenceError: Can't find variable: Intl
Here's my entire spec file:
import { provide, PLATFORM_PIPES } from '#angular/core';
import { DatePipe } from '#angular/common';
import { addProviders, async, inject } from '#angular/core/testing';
import { Post, PostComponent, PostHtmlComponent } from './';
import { usingComponentFixture } from '../../test-helpers';
describe('Component: Post', () => {
beforeEach(() => {
provide(PLATFORM_PIPES, {useValue: DatePipe, multi: true });
addProviders([PostComponent, PostHtmlComponent, ]);
});
it('should render an h1 tag with text matching the post title',
usingComponentFixture(PostComponent, fixture => {
let component = <PostComponent>fixture.componentInstance;
let element = fixture.nativeElement;
component.post = <Post>{ title: 'Hello', publishedOn: new Date('8/5/2016') };
fixture.detectChanges();
expect(element.querySelector('.blog-post-header h1').innerText).toBe('Hello');
})
);
});
And this is the component template:
<div class="col-lg-8 col-md-7 col-sm-6">
<h1>{{post.title}}</h1>
<p class="lead">{{post.publishedOn | date:'fullDate'}}</p>
</div>
I was able to resolve this issue. Here's what I had to do:
npm install karma-intl-shim --save-dev
Add 'intl-shim' to the frameworks collection in karma.conf.js
Add the following to karma-test-shim.js (this is referenced in the files collection of karma.conf.js)
require('karma-intl-shim');
require('./en-us.js'); // copied from https://github.com/andyearnshaw/Intl.js/blob/master/locale-data/json/en-US.json
Intl.__addLocaleData(enUsLocaleData);
Instead of mocking the DatePipe, you can use the transform method of DatePipe in typescript which is equivalent to the | operator in the HTML file
import {DatePipe} from '#angular/common';
let pipe = new DatePipe('en');
expect(page.myDate.nativeElement.innerHTML).toBe(pipe.transform(model.date, 'dd/MM/yyyy');
For tests I mock date pipe:
#Pipe({
name: 'date',
pure: false // required to update the value when the promise is resolved
})
export class MockedDatePipe implements PipeTransform {
name: string = 'date';
transform(query: string, ...args: any[]): any {
return query;
}
}
Then when I configure testing module I inject it into declaration:
TestBed.configureTestingModule( {
providers: [
SelectionDispatcher,
{ provide: MyService, useClass: MockedMyServiceService }
],
declarations: [ MyComponent, MockedTranslatePipe, MockedDatePipe ]
});
That worked for me:
import { DatePipe, registerLocaleData } from '#angular/common';
import localeDe from '#angular/common/locales/de';
registerLocaleData(localeDe);
//..
describe('My Test', () => {
let pipe = new DatePipe('de-DE');
it('My Test-Case', () => {
expect(page.myDate.nativeElement.innerHTML).toBe(pipe.transform(model.date);
});
});
You must set the right locale.
That is a snippet from a Cypress-Test.
that's what worked for me:
import {DatePipe} from "#angular/common";
...
TestBed.configureTestingModule({
...
providers: [DatePipe]
...
});
Expanding on other answers on here I was using the DatePipe in my component to produce a payload. I had the following setup.
Return the transform method on DatePipe in the mock, matching parameters used by the component i.e. ('YY'). Otherwise we will just get undefined as the value when testing.
.spec file
import { DatePipe } from '#angular/common';
.....
const mockDatePipe = {
transform: jest.fn((val) => new DatePipe('en').transform(val, 'YY')),
};
.....
beforeEach(() => {
component = new TestComponent(
(mockDatePipe as unknown) as DatePipe,
.....
);
});
it('should return correct payload', () => {
expect(component.getPayload(new Date('2022-02-02')).toEqual(
{
purchaseYear: '22',
}
}
.ts file
public getPayload(date: new Date(), .....){
return {
purchaseYear: this.datePipe.transform(date, 'YY')
};
);
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;
http://plnkr.co/edit/q1l1y8?p=preview
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:
<div id="task-list">
<div *ngFor="let task of (tasks$ | async)">
<app-task [task]="task" (click)="refresh()"></app-task>
</div>
</div>
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 real app-taskcomponent.
so as #Klas suggested we can configure our TestModule with:
schemas: [CUSTOM_ELEMENTS_SCHEMA]
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):
#Directive({
selector: 'app-task'
})
class MockTaskDirective {
#Input('task')
public task: ITask;
#Output('click')
public clickEmitter = new EventEmitter<void>();
}
Now we'll declare it in the testing module:
let fixture : ComponentFixture<TaskListComponent>;
let cmp : TaskListComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TaskListComponent, **MockTaskDirective**],
// schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{
provide: TasksService,
useClass: MockService
}
]
});
fixture = TestBed.createComponent(TaskListComponent);
**fixture.autoDetectChanges();**
cmp = fixture.componentInstance;
});
Notice that because the generation of sub component of the fixture is happening asynchronously after its creation, we activate its autoDetectChanges feature.
In our tests, we can now query for the directive, access its DebugElement's injector, and get our mock directive instance through it:
import { By } from '#angular/platform-browser';
const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
const mockTaskCmp = mockTaskEl.injector.get(MockTaskDirective) as MockTaskDirective;
[This part should usually be in the beforeEach section, for cleaner code.]
From here, the tests are a piece of cake :)
it('should contain task component', ()=> {
// Arrange.
const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
// Assert.
expect(mockTaskEl).toBeTruthy();
});
it('should pass down task object', ()=>{
// Arrange.
const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
const mockTaskCmp = mockTaskEl.injector.get(MockTaskDirective) as MockTaskDirective;
// Assert.
expect(mockTaskCmp.task).toBeTruthy();
expect(mockTaskCmp.task.name).toBe('1');
});
it('should refresh when task is clicked', ()=> {
// Arrange
spyOn(cmp, 'refresh');
const mockTaskEl = fixture.debugElement.query(By.directive(MockTaskDirective));
const mockTaskCmp = mockTaskEl.injector.get(MockTaskDirective) as MockTaskDirective;
// Act.
mockTaskCmp.clickEmitter.emit();
// Assert.
expect(cmp.refresh).toHaveBeenCalled();
});
If you use schemas: [CUSTOM_ELEMENTS_SCHEMA]in TestBed the component under test will not load sub components.
import { CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { TestBed, async } from '#angular/core/testing';
import { MyComponent } from './my.component';
describe('App', () => {
beforeEach(() => {
TestBed
.configureTestingModule({
declarations: [
MyComponent
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
});
it(`should have as title 'app works!'`, async(() => {
let fixture = TestBed.createComponent(MyComponent);
let app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('Todo List');
}));
});
This works in the released version of Angular 2.0.
Full code sample here.
An alternative to CUSTOM_ELEMENTS_SCHEMA is NO_ERRORS_SCHEMA
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.html
It 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
import {MyNavbarComponent} from '../src/my-navbar.component';
import {MyToolbarComponent} from '../src/my-toolbar.component';
#Component({template:''})
class EmptyComponent{}
describe('MyComponent', () => {
beforeEach(injectAsync([TestComponentBuilder], (tcb) => {
return tcb
.overrideDirective(MyComponent, MyNavbarComponent, EmptyComponent)
.overrideDirective(MyComponent, MyToolbarComponent, EmptyComponent)
.createAsync(MyComponent)
.then((componentFixture: ComponentFixture) => {
this.fixture = componentFixture;
});
));
it('should bind to {{foo}}', () => {
let el = this.fixture.nativeElement;
let myComponent = this.fixture.componentInstance;
myComponent.foo = 'FOO';
fixture.detectChanges();
expect(el.innerHTML).toMatch('FOO');
});
});
I put together a simple MockComponent module to help make this a little easier:
import { TestBed } from '#angular/core/testing';
import { MyComponent } from './src/my.component';
import { MockComponent } from 'ng2-mock-component';
describe('MyComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
MyComponent,
MockComponent({
selector: 'my-subcomponent',
inputs: ['someInput'],
outputs: [ 'someOutput' ]
})
]
});
let fixture = TestBed.createComponent(MyComponent);
...
});
...
});
It's available at
https://www.npmjs.com/package/ng2-mock-component.