I am trying to test a Subject change in my component, but the coverage never enters into the subscribe function.
titlebar-search.component.ts
export class TitlebarSearch implements OnInit {
@ViewChild('titleSearchInput') titleSearchInputEl: any;
@Input() inputValue: string;
@Output() searchText = new EventEmitter<string>();
searchChange: Subject<string> = new Subject<string>();
constructor(private renderer: Renderer) {
}
/**
* Waits a time before send the text to search
*
* @protected
* @memberof TitlebarSearch
*
*/
protected prepareSearchInput() {
this.searchChange.debounceTime(500).subscribe(value => {
this.searchText.emit(value);
});
}
/**
* Send the text to the searchChange Observable
*
* @param {string} text
* @memberof TitlebarSearch
*/
public doSubmit(text:string){
this.searchChange.next(text);
}
}
titlebar-search.component.spec.ts
describe('Titlebar Search tests', () => {
let fixture;
let titlebarComponent;
beforeEach(async(() => {
//Creates a UserService using a mock class
TestBed.configureTestingModule({
declarations: [TitlebarSearch],
imports: [FormsModule],
//CUSTOM_ELEMENTS_SCHEMA to solve html elements issues
schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
providers: [Renderer]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(TitlebarSearch);
titlebarComponent = fixture.componentInstance
});
}));
//specs
it('should send the text to detect the change', async((done) => {
const text = "Changed text";
titlebarComponent.doSubmit(text);
fixture.detectChanges();
titlebarComponent.searchChange.subscribe(textRecived => {
expect(textRecived).toEqual(text);
done();
})
}));
});
The doSubmit method, is called when the input text had been changed. Then the prepareSearchInput has a subscription to the subject to get the next with debounce and output the same text.
I don't know where is the mistake in the test, but the coverage never cover the subscription code. The examples over Internet did't help me.
I had the same problem, but got the answer from @jonrsharpe in this thread: Unit test Angular 2 service subject.
You need to declare your subject subscription earlier in your test, before the next()
is called. If you reorder it like this, it should work:
it('should send the text to detect the change', async((done) => {
titlebarComponent.searchChange.subscribe(textRecived => {
expect(textRecived).toEqual(text);
done();
})
const text = "Changed text";
titlebarComponent.doSubmit(text);
fixture.detectChanges();
}));
The problem, according to John, was that your subject didn't have any replay/buffer behaviour.