0

I'm trying to fill out a form in Angular 4 and test the result. Here's the component:

import { Component } from '@angular/core';
import { Validators, FormBuilder, FormGroup } from '@angular/forms';
import { NavController, NavParams } from 'ionic-angular';
import { Angular2TokenService } from 'angular2-token';

@Component({
  selector: 'page-create-account',
  templateUrl: 'create_account.html'
})
export class CreateAccountPage {
  private account : FormGroup;
  selectedItem: any;
  icons: string[];
  items: Array<{title: string, note: string, icon: string}>;

  constructor(public navCtrl: NavController, public navParams: NavParams, private formBuilder: FormBuilder, private _tokenService: Angular2TokenService) {
    this.account = this.formBuilder.group({
      first_name: ['', Validators.required],
      last_name: ['', Validators.required],
      email: ['', Validators.required],
      password: ['', [Validators.required, Validators.minLength(8)]],
      passwordConfirmation: [''],
    });
  }

  createAccount() {
    this.account.value['passwordConfirmation'] = this.account.value['password'];
    this._tokenService.registerAccount(this.account.value).subscribe(
        res =>      this.navCtrl.push(StartListingPage),
        error =>    console.log(error)
    );
  }

  login(event) {
    this.navCtrl.setRoot(LoginAccountPage);
  }
}

This is my template:

<ion-header>
  <ion-navbar>
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Create Account</ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <form [formGroup]="account" (ngSubmit)="createAccount()">
    <ion-list>
      <ion-item>
        <ion-label floating>First Name</ion-label>
        <ion-input type="text" formControlName="first_name"></ion-input>
      </ion-item>

      <ion-item>
        <ion-label floating>Last Name</ion-label>
        <ion-input type="text" formControlName="last_name"></ion-input>
      </ion-item>

      <ion-item>
        <ion-label floating>Email</ion-label>
        <ion-input type="text" formControlName="email"></ion-input>
      </ion-item>

      <ion-item>
        <ion-label floating>Password</ion-label>
        <ion-input type="password" formControlName="password"></ion-input>
      </ion-item>
    </ion-list>

    <div style="width:90%; margin: 0px auto; text-align:center;">
      <button ion-button block type="submit" [disabled]="!account.valid">Create Account</button>
      <div style="margin-top:20px;"><a (click)="login()">Already Have an Account? Login!</a></div>
    </div>
  </form>
</ion-content>

So I created the following spec:

import { Nav, Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { Angular2TokenService } from 'angular2-token';
import { TestBed, getTestBed, ComponentFixture, async } from '@angular/core/testing';
import { IonicModule } from 'ionic-angular';
import { By }              from '@angular/platform-browser';
import { DebugElement }    from '@angular/core';
import { Validators, FormBuilder, FormGroup } from '@angular/forms';
import { NavController, NavParams } from 'ionic-angular';
import { CreateAccountPage } from './create_account';

let comp: CreateAccountPage;
let fixture: ComponentFixture<CreateAccountPage>;

class MockNavParams {
  data = { };
}

describe('CreateAccountPage', () => {
    beforeEach(async(() => {
        let tokenMock = jasmine.createSpyObj('tokenMock', ['registerAccount', 'subscribe']);
        tokenMock.registerAccount.and.returnValue(tokenMock);
        TestBed.configureTestingModule({
            declarations: [ CreateAccountPage ],
            providers: [ NavController, FormBuilder,
                { provide: Angular2TokenService, useValue: tokenMock },
                { provide: NavParams, useClass: MockNavParams},
            ],
            imports: [
                IonicModule.forRoot(CreateAccountPage)
            ],
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(CreateAccountPage);
        comp    = fixture.componentInstance;
    });

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

    it('should create account when clicked', () => {    
        fixture.detectChanges();
        let inputs = fixture.debugElement.queryAll(By.css('input'));

        let first = inputs[0].nativeElement;
        first.value = 'Jason';
        first.dispatchEvent(new Event('input'));
        expect(comp.account.value['first_name']).toBe('Jason');

        let form = fixture.debugElement.query(By.css('form'));
        form.triggerEventHandler('submit', null);
        // The above works or this line also works:
        //form.nativeElement.dispatchEvent(new Event('submit'));
        expect(comp.createAccount).toHaveBeenCalled;

        let tokenMock = getTestBed().get(Angular2TokenService);
        expect(tokenMock.registerAccount).toHaveBeenCalledWith({
            first_name: 'Jason',
            last_name: '',
            email: '',
            password: '',
            passwordConfirmation: ''
        });
    });
});

My test result says that registerAccount is called but with all the fields blank. So I think I'm close but I can't figure out how to fill the form. Any ideas?

EDIT: I found code online which seems to indicate I need to dispatch the event to the Angular system so I added that but still no dice.

SUCCESS: I was previously grabbing the wrong element in the By.css selection. I updated the example above to my working solution.

1 Answer 1

1

I updated the spec above to my working solution. The main problem was I wasn't calling first.dispatchEvent(new Event('input')); and I also had a bad CSS selection in my By.css line.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.