首页 文章

测试角度表单提交

提问于
浏览
0

我正在测试一个角度应用程序,特别是这个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));
        }
    }
}

这是我的patient.model.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,sex等 .

2.对于第二次测试,我在一个角度教程中读到它: HaveBennCalled(0) 是测试这个 Spy 是否被调用以及多少次的正确方法 . 但无论如何它确实测试按钮是否调用函数save() . 我认为它只检查之前是否没有调用按钮,但是如果它现在在保存功能中被调用则不会 .

  1. And are these 3 tests enough and complete for a form submitting?

1 回答

  • 1

    根据我的意见,这里是如何测试表单是否正确提交 .

    假设您有一个接口 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
    });
    

    这些测试的一般想法是 to cover any case that could happen . 这将允许您防止副作用:例如,如果有一天您决定将您的ID传递给字符串,单元测试将失败并告诉您

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

    这是单元测试的目的 .

相关问题