2016-11-21 70 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] 
)} 

也许这可以帮到您?