代码之家  ›  专栏  ›  技术社区  ›  Tester

测试角度表单提交

  •  1
  • Tester  · 技术社区  · 7 年前

    我正在测试angular应用程序,尤其是这个HTML输入:

    <form  name="editForm" role="form" novalidate (ngSubmit)="save()" #editForm="ngForm">
         <input type="text" name="nombre" id="field_nombre"
        	                [(ngModel)]="paciente.nombre" required/>
    (etc. f.e. button on submit...)
    这是我的组件:

    imports....
    
    
    export class PacienteDialogComponent implements OnInit {
        
        paciente: Paciente;
        
        ....
        
           save() {
            this.isSaving = true;
            if (this.paciente.id !== undefined) {
                this.subscribeToSaveResponse(
                    this.pacienteService.update(this.paciente));
            } else {
                this.subscribeToSaveResponse(
                    this.pacienteService.create(this.paciente));
            }
        }
    }
    这是我的病人。模型ts

    export class Paciente implements BaseEntity {
        constructor(
            public id?: number,
            public nombre?: string,
            public sexo?: Sexo,
            
            .....
    我想测试表单,这意味着在提交时它实际上是在调用save()函数。 我的测试中有:

    describe('Paciente Management Dialog Component', () => {
            let comp: PacienteDialogComponent;
            let fixture: ComponentFixture<PacienteDialogComponent>;
            let debugElement: DebugElement; //create a debgElement for testing
    
            beforeEach(async(() => {
                TestBed.configureTestingModule({
                    imports: [OncosupTestModule,
                        OncosupSharedModule,
                        BrowserModule,
                        FormsModule,
                      
                    ],
                    declarations:...
                    ],
                    providers: [
                        ...
                })
                .compileComponents();
            }));
    
      beforeEach(() => {
                fixture = TestBed.createComponent(PacienteDialogComponent);
                comp = fixture.componentInstance;
                debugElement = fixture.debugElement;
            });
                    //a default generated test which controls if the save method really saves a new patient with its name, id, sex, etc.
            it('Should call create service on save for new entity',
               inject([],
                   fakeAsync(() => {
                       // GIVEN
                       const entity = new Paciente();
                       spyOn(service, 'create').and.returnValue(Observable.of(new HttpResponse({body: entity})));
                       comp.paciente = entity;
                       // WHEN
                       comp.save();
                       tick(); // simulate async
    
                       // THEN
                       expect(service.create).toHaveBeenCalledWith(entity);
                       expect(comp.isSaving).toEqual(false);
                       expect(mockEventManager.broadcastSpy).toHaveBeenCalledWith({ name: 'pacienteListModification', content: 'OK'});
                       expect(mockActiveModal.dismissSpy).toHaveBeenCalled();
                   })
               )
           );
    // And teh second thing I want to test is if ngSubmit is really calling the save() function
    
    
               it ('should call the onSubmit method', async(() => {
                //fixture.detectChanges();
                spyOn(comp,'save');
                var1 = debugElement.query(By.css('button')).nativeElement;
                console.log('print button ' + var1);
                var1.click();
                expect(comp.save).toHaveBeenCalledTimes(0);//verify...
                }));
    
    //And also if isSaving is set to true
    
    
     it ('should set isSaving to true', async(() => {
               comp.save();
                expect(comp.isSaving).toBeTruthy();
             
               }));
    
    
    
    
    
             
            
            

    1、现在我有这些问题:第一个测试是默认生成的,不是我写的。在此行中 const entity = new Paciente(); 我应该调用Paciente的参数吗?比如id、sex、name,或者默认情况下不带参数。第一个测试的目的是检查save()函数是否真的保存了患者及其id、性别等数据。

    2、对于第二个测试,我在angular教程中读到: HaveBennCalled(0) 是测试这个间谍是否被调用以及调用次数的正确方法。但无论如何,它确实测试了按钮是否调用函数save()。我认为它只检查按钮以前是否没有被调用过,但不检查它现在是否在保存功能中被调用。

    3. 对于提交表格来说,这三项测试是否足够完整?

    1 回复  |  直到 7 年前
        1
  •  1
  •   user4676340 user4676340    7 年前

    在我的评论之后,下面是如何测试表单是否正确提交。

    假设您有一个接口 Patient :

    export interface Patient {
      id: number;
      name: string;
    }
    

    在组件中,您有一个表单,可以通过 submit() :

    submit() {
      this.patientService.savePatient(this.patient).subscribe(result => {
        console.log('Patient created');
      });
    }
    

    现在,您的服务进行HTTP调用并检查字段是否正常:

    savePatient(patient: Patient): Observable<any> {
      if (typeof patient.id !== number) { return Observable.throw('ID is not a number'); }
      if (typeof patient.name !== string) { return Observable.throw('Name is not a string'); }
    
      return this.http.post<any>(this.url, patient);
    }
    

    那么你的测试应该是这样的。首先,组件:

    it('Should call the service to save the patient in DB', () => {
      // Spy on service call
      // Expect spy to have been called
    });
    
    it('Should log a message on success', () => {
      // Spy on console log
      // Expect console log to have been called with a string
    });
    

    您还可以测试错误处理是否正确,是否有错误代码等。

    现已投入使用:

    it('Should throw an error if the ID is not a number', () => {
      // Mock a patient with a string ID
      // Expect an error to be thrown
    });
    
    // Same thing for the name, you get the idea
    
    it('Should make an HTTP call with a valid patient', () => {
      // Spy on the HttpTestingController
      // Expect the correct endpoint to have been called, with the patient as the payload
    });
    

    这些测试的总体思路是 涵盖任何可能发生的情况 。这将允许您防止 副作用 :例如,如果有一天您决定将ID传递给字符串,那么单元测试将失败并告诉您

    你希望我发送一个字符串,但我只传递一个数字

    这是单元测试的目的。