2016-11-21 101 views
4

我有一個簡單的組件,其中包含form元素中的兩個輸入字段。點擊提交按鈕後,它會調用組件上的addUser函數。下面Angular2 - 單元測試表單提交

組件模板給出:

<div> 
    <form [formGroup]="signupForm" (submit)="addUser($event)" role="form" class="form-horizontal"> 
     <label>Firstname:</label> 
     <input type="text" formControlName="firstName"> 
     <label>Lastname:</label> 
     <input type="text" formControlName="lastName"> 
     <input type="submit" id="btnSubmit" class="btn btn-primary btn-lg" value="Register" /> 
    </form> 
</div> 

組件定義如下:

@Component({ 
    moduleId: module.id, 
    templateUrl: 'user.component.html' 
}) 
export class UserComponent { 

    registered = false; 

    constructor(
    private router: Router, 
    private fb: FormBuilder, 
    public authService: AuthService) { 

     this.signupForm = this.fb.group({ 
      'firstName': ['', Validators.required], 
      'lastName': ['', Validators.required] 
     });   
    } 

    addUser(event: any) { 
     event.preventDefault(); 
     this.addUserInvoked = true; 
     ...... 
     ...... 
     this.authService.register(this.signupForm.value) 
     .subscribe(
     (res: Response) => { 
      if (res.ok) { 
       this.registered = true; 
      } 
     }, 
     (error: any) => { 
      this.registered = false;         
     }); 
    } 
} 

它工作正常。然而,在我的單元測試中,當我嘗試測試在提交按鈕上單擊時調用addUser的調用。但不幸的是addUser函數沒有被調用。

下面是我的樣本單元測試

class RouterStub { 
    navigateByUrl(url: string) { return url; } 
} 


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

describe('UserComponent',() => { 
    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ UserComponent ], 
     schemas:  [NO_ERRORS_SCHEMA] 
    }); 
    }); 

    compileAndCreate(); 
    tests(); 
}); 

function compileAndCreate() { 
    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     providers: [   
     { provide: Router,  useClass: RouterStub }, 
     { provide: AuthService, useValue: authServiceStub }, 
     FormBuilder 
     ] 
    }) 
    .compileComponents().then(() => { 
     fixture = TestBed.createComponent(UserComponent); 
     comp = fixture.componentInstance; 
    }); 
    })); 
} 

function tests() { 
    it('should call addUser when submitted',() => { 
     const spy = spyOn(comp, 'addUser'); 

     //*************below method doesn't work and it refreshes the page*************** 
     //let btnSubmit = fixture.debugElement.query(By.css('#btnSubmit')); 
     //btnSubmit.nativeElement.click(); 

     let form = fixture.debugElement.query(By.css('form')); 
     form.triggerEventHandler('submit', null); 
     fixture.detectChanges(); 

     expect(comp.addUser).toHaveBeenCalled(); 
     expect(authServiceStub.register).toHaveBeenCalled(); 
     expect(comp.registered).toBeTruthy('user registered'); 
    }); 

} 

我已經試過

fixture.debugElement.query(By.css('#btnSubmit')).nativeElement.click() 

fixture.debugElement.query(By.css('form')).triggerEventHandler('submit', null) 

,但我仍然無法調用addUser功能。我看過一個已經發布在SO here上的問題,但它也沒有幫助。

+0

哪一步失敗? 'expect(comp.addUserInvoked).toBeTruthy();'是一個不準確的期望,因爲如果你實際上沒有調用永遠不會被設置的方法。 – jonrsharpe

+0

這是一個虛擬的期望,只是爲了測試提交函數被調用。 –

+0

但那是失敗的嗎?因爲這個函數沒有被調用,*間諜是*,並且你不通過。你能給[mcve]輸出嗎? – jonrsharpe

回答

1

我有同樣的問題,我的解決方案是我不得不將'FormsModule'導入到我的測試模塊的配置中。

TestBed.configureTestingModule({ 
      imports: [FormsModule] 
)} 

也許這可以幫到您?