11

I have a text input and i'm listening for the changes.

mycomponent.ts

ngOnInit() {
    this.searchInput = new Control();
    this.searchInput.valueChanges
        .distinctUntilChanged()
        .subscribe(newValue => this.search(newValue))
}
search(query) {
    // do something to search
}

mycomponent.html

<search-box>
    <input type="text" [ngFormControl]="searchInput" >
</search-box>

Running the application everything works fine, but i want to unit-test it.

So here's what i tried

mycomponent.spec.ts

beforeEach(done => {
    createComponent().then(fix => {
        cmpFixture = fix
        mockResponse()
        instance = cmpFixture.componentInstance
        cmpFixture.detectChanges();
        done();
    })
})
describe('on searching on the list', () => {
        let compiled, input
        beforeEach(() => {
            cmpFixture.detectChanges();
            compiled = cmpFixture.debugElement.nativeElement;
            spyOn(instance, 'search').and.callThrough()
            input = compiled.querySelector('search-box > input')
            input.value = 'fake-search-query'
            cmpFixture.detectChanges();
        })
        it('should call the .search() method', () => {
            expect(instance.search).toHaveBeenCalled()
        })
    })

Test fails as the .search() method is not called.

I guess i have to set the value in another way to have the test realize of the change but i really don't know how.

Anyone has ideas?

Bolza
  • 1,904
  • 2
  • 17
  • 42

3 Answers3

25

It might be a little bit late, but it seems that your code is not dispatching input event after setting input element value:

// ...    
input.value = 'fake-search-query';
input.dispatchEvent(new Event('input'));
cmpFixture.detectChanges();
// ...

Updating input html field from within an Angular 2 test

Andrius
  • 947
  • 15
  • 22
0

Triggering the value change of FormControl is as simple as:

cmpFixture.debugElement.componentInstance.searchInput.setValue(newValue);
kimamula
  • 11,427
  • 8
  • 35
  • 29
0

Custom component with @input, subscriptions, two way data binding

If you got a custom component you would need further changes in your application to be able to successfully unit test your application

have a look at the gist here this will give you some idea https://gist.github.com/AikoPath/050ad0ffb91d628d4b10ef81736af386/raw/846c7bcfc54be8cce78eba8d12015bf749b91eee/@ViewChild(ComponentUnderTestComponent).js

More over complete reading over here carefully otherwise you can easily get confused again - https://betterprogramming.pub/testing-angular-components-with-input-3bd6c07cfaf6

TARJU
  • 1,785
  • 1
  • 14
  • 16