this is from official documentation https://angular.io/docs/ts/latest/guide/testing.html#!#component-fixture. So you can create new input object expectedHero and pass it to the component comp.hero = expectedHero
Also make sure to call fixture.detectChanges(); last, otherwise property will not be bound to component.
Working Example
// async beforeEach
beforeEach( async(() => {
TestBed.configureTestingModule({
declarations: [ DashboardHeroComponent ],
})
.compileComponents(); // compile template and css
}));
// synchronous beforeEach
beforeEach(() => {
fixture = TestBed.createComponent(DashboardHeroComponent);
comp = fixture.componentInstance;
heroEl = fixture.debugElement.query(By.css('.hero')); // find hero element
// pretend that it was wired to something that supplied a hero
expectedHero = new Hero(42, 'Test Name');
comp.hero = expectedHero;
fixture.detectChanges(); // trigger initial data binding
});
Answer from Vazgen Manukyan on Stack Overflowthis is from official documentation https://angular.io/docs/ts/latest/guide/testing.html#!#component-fixture. So you can create new input object expectedHero and pass it to the component comp.hero = expectedHero
Also make sure to call fixture.detectChanges(); last, otherwise property will not be bound to component.
Working Example
// async beforeEach
beforeEach( async(() => {
TestBed.configureTestingModule({
declarations: [ DashboardHeroComponent ],
})
.compileComponents(); // compile template and css
}));
// synchronous beforeEach
beforeEach(() => {
fixture = TestBed.createComponent(DashboardHeroComponent);
comp = fixture.componentInstance;
heroEl = fixture.debugElement.query(By.css('.hero')); // find hero element
// pretend that it was wired to something that supplied a hero
expectedHero = new Hero(42, 'Test Name');
comp.hero = expectedHero;
fixture.detectChanges(); // trigger initial data binding
});
If you use TestBed.configureTestingModule to compile your test component, here's another approach. It's basically the same as the accepted answer, but may be more similar to how angular-cli generates the specs. FWIW.
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DebugElement } from '@angular/core';
describe('ProductThumbnail', () => {
let component: ProductThumbnail;
let fixture: ComponentFixture<TestComponentWrapper>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
TestComponentWrapper,
ProductThumbnail
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.compileComponents();
fixture = TestBed.createComponent(TestComponentWrapper);
component = fixture.debugElement.children[0].componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@Component({
selector: 'test-component-wrapper',
template: '<product-thumbnail [product]="product"></product-thumbnail>'
})
class TestComponentWrapper {
product = new Product()
}
Videos
Make sure to assign the required input before getting the component instance from the fixture
In your code:
fixture.componentRef.setInput('required', 'foo');
component = fixture.componentInstance;
try this
describe('ComponentComponent', () => {
let component: ComponentComponent;
beforeEach(async () => {
await TestBed.configureTestingModule({
providers: [ ComponentComponent ]
});
component = TestBed.inject(ComponentComponent);
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
the following works:
Include this import:
import { of } from 'rxjs';
Change the beforeEach block for the file to:
beforeEach(() => {
fixture = TestBed.createComponent(BugsTableComponent);
component = fixture.componentInstance;
// needed because ngAfterViewInit gets called and if there isn't an observable to subscribe to it will fail
component.bugsDataService = of(null);
fixture.detectChanges();
});
Write a test:
it('Should assign the input value to bugsdata', () => {
// Arrange
component.bugsData = {}; // to make sure it's empty at the start
const resultFromService = {hello: 'world'};
component.bugsDataService = of(resultFromService); // this creates an observable from resultFromService
// Act
component.ngAfterViewInit();
// Assert
expect(component.bugsData).toEqual(resultFromService);
});
Some notes:
- I've noticed is that your component has a
ngAfterViewInitbut the class does not implement it. If you're not usingngOnInitthen replace it in the class declaration withngAfterViewInitand update the imports. - If you don't want to do the change I suggested in the beforeEach block you can move the subscribe line from
ngAfterViewInitto a separate method that is called byngAfterViewInit. However, you'll then need to spy on it so it doesn't actually get called.
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BugsTableComponent ],
imports: [],
providers: [BugsDataService] // inject service here
})
.compileComponents();
}));
This should fix the bug but
If you want to Simulate the actual behaviour of the service better way would be to create a mock service which extends BugsDataService and use it in the unit test cases to provide Mock Data
example
@Injectable()
export class BugsDataMockService extends BugsDataService {
overridenMethod() {
return Observable.of( { data : yourmockresponse });
}
And in your Spec file (Unit test)
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BugsTableComponent ],
imports: [],
providers: [ { provide: BugsDataService, useClass: BugsMockDataService } ] // Use Mock Service instead of original one
})
.compileComponents();
}));