lathonez / clicker

Ionic 2 + @angular/cli Seed Project : Angular2 + Typescript + Karma + Protractor + Travis
http://lathonez.com/2018/ionic-2-unit-testing/
MIT License
430 stars 137 forks source link

Is there any possiblity to test the validators and input fields in the form? #259

Closed jainAdijain closed 7 years ago

jainAdijain commented 7 years ago

Hi Lathonez,

I saw your ClickerForm which helps a lot to understand about testing forms in ionic.I have certain queries which I have not understood, please help me.

 it('passes new clicker through to service', () => {
    let clickerName: string = 'dave';
    instance.form = new FormBuilder().group({clickerNameInput: [clickerName]});
    spyOn(instance, 'newClicker').and.callThrough();
    spyOn(instance['clickerService'], 'newClicker').and.callThrough();
    fixture.detectChanges();
    fixture.nativeElement.querySelectorAll('button')[0].click(); **//not understood!!!**
    expect(instance.newClicker).toHaveBeenCalledWith(Object({ clickerNameInput: clickerName }));
    expect(instance['clickerService'].newClicker).toHaveBeenCalledWith(clickerName);
  });

I have written a comment in the line which is third last, please explain me the function of querySelectorAll on the buttonand[0].

Secondly, I wrote some lines of code following yours but, but got an error stating- Expected spy onSubmit to have been called with [ Object({ name: 'Aditya', email: 'test@aaa.com' }) ] but it was never called.

form.ts

@Component({
  selector: 'page-form',
  templateUrl: 'form.html',
})
export class Form {

  public form: FormGroup;

  constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.group({
      name: ['', Validators.required],
      email: ['', Validators.email],
    });
  }
  onSubmit(formValue: Object): boolean {
    this.form.controls['name'].markAsTouched();
    this.form.controls['email'].markAsTouched();
if(!this.form.controls['name'].valid && !this.form.controls['email'].valid){
      return false;
    }
    this.form.reset();
  }
}

form.spec.ts


import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { Form } from './form';
import { IonicModule } from 'ionic-angular';
import { DebugElement } from "@angular/core";
import { By } from "@angular/platform-browser";
import { FormBuilder } from '@angular/forms';

describe('Form', () => {

    let fixture: ComponentFixture<Form>;
    let comp: Form;
    let de: DebugElement;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [Form],
            imports: [
                IonicModule.forRoot(Form)
            ]
        }).compileComponents();
    }));
    beforeEach(() => {
        fixture = TestBed.createComponent(Form);
        comp = fixture.componentInstance;
        // de = fixture.debugElement.query(By.css(''))
    });

    afterEach(() => {
        fixture.destroy();
    })

    it('initialises the form', () => {
        expect(comp).toBeTruthy();
        expect(fixture).toBeTruthy();
        expect(comp).not.toBeNull();
        expect(fixture).not.toBeNull();
    });

    it('use of spy', () => {
        let Username: string = 'Aditya';
        let Email: string = 'test@aaa.com';
        comp.form = new FormBuilder().group({ name: [Username], email: [Email] });
        spyOn(comp, 'onSubmit').and.callThrough();
        fixture.detectChanges();
        fixture.nativeElement.querySelectorAll('button')[0].click();
        expect(comp.onSubmit).toHaveBeenCalledWith(Object({ name: Username, email: Email }));
    });

})

Lastly, Can't we have a use case for input fields and validators and submit button?

Thank you

lathonez commented 7 years ago

Hey,

If you have a general question about unit testing (e.g. how can I write a unit test for some-module), see #191

Thanks,

Stephen

jainAdijain commented 7 years ago

Hi, I am not able to ask questions on stack overflow due to exceeding asking questions limit. Please help if it is possible, it will be very helpful and will add some knowledge.

Thank you

Aditya