2017-08-22 69 views
12

Stworzyłem szereg testów jednostkowych dla komponentu, który posiadam. Pierwotnie zawodziło, ponieważ dostałem powyższy błąd, więc wyjąłem event.defaultPrevented, nie wiedząc, co robi.Błąd testu jednostki Angular 2 Nie można uzyskać właściwości "preventDefault" niezdefiniowanej lub zerowej wartości zadanej

Cóż, to naprawiło moje błędy, ale oczywiście miało bardzo zły efekt uboczny na zachowanie interfejsu, więc musiałem umieścić te rzeczy z powrotem w moim kodzie.

Tak, teraz wracam do naprawiania testów jednostkowych. Jak mogę udawać/wstrzykiwać rzeczy z imprezy w moje testy jednostkowe?

Tylko domyślny „powinien tworzyć” test, który jest zgaszone przez Kątowymi CLI zawodzi, oto kod:

let component: MemberAddComponent; 
let fixture: ComponentFixture<MemberAddComponent>; 
let contractsService: ContractsService; 
let notesService: NotesService; 
let saveButton: any; 

beforeEach(async(() => { 
    let router = { navigate: jasmine.createSpy('navigate') }; 

    TestBed.configureTestingModule({ 
     imports: [ 
      HttpModule, 
      FormsModule, 
      ReactiveFormsModule, 
      RouterTestingModule 
     ], 
     declarations: [ 
      MemberAddComponent, 
      // lots more here 
     ], 
     providers: [ 
      AppDataService, 
      ErrorService, 
      { 
       provide: ContractsService, 
       useClass: MockContractsService 
      }, 
      { 
       provide: NotesService, 
       useClass: MockNotesService 
      } 
     ] 
    }) 
    .compileComponents(); 
})); 

beforeEach(() => { 
    fixture = TestBed.createComponent(MemberAddComponent); 
    component = fixture.componentInstance; 
    contractsService = fixture.debugElement.injector.get(ContractsService); 
    saveButton = fixture.nativeElement.querySelector('#saveButton'); 
    fixture.detectChanges(); 
}); 

it('should create',() => { 
    expect(component).toBeTruthy(); 
}); 

A oto funkcja ngOnInit które powinny być jedyną rzeczą uruchomiony dla tego testu:

ngOnInit() { 
    this.log('ngOnInit', 'ngOnInit...'); 

    this.routeSubscription = this.route.params.subscribe(params => { 
     this.memberId = params['id'] || null; 
     this.effectiveDate = params['from'] || null; 
     this.cancelDate = params['to'] || null; 
     this.group = params['group'] || null; 
     this.subgroup = params['subgroup'] || null; 
    }); 

    this.contractRequest = new models.AddContractRequestUI(); 

    this.dataservice.effectiveDateOfChange = this.dataservice.getCurrentDateMountainTimezone(); 
    this.dataservice.todaysDateString = this.dataservice.effectiveDateOfChange; 

    if (this.contractRequest.subscriber.class.length === 0) { 
     this.contractRequest.subscriber.class.push(new models.AddContractRequestSubscriberClass(this.dataservice.effectiveDateOfChange)); 
    } 

    this.loadContractDetails(); 

    this.dependent.originalEffectiveDt = this.dataservice.effectiveDateOfChange; 
    this.memberComplete = false; 
    this.transactionStartTime = new Date(); 
} 

Edit: powiadomienie nie jest event.preventDefault lub event.defaultPrevented gdziekolwiek w kodzie, który jest przetestowany. To istnieje tylko w funkcji onSubmit dla procesu post/submit na tym komponencie. Ale nadal sprawia, że ​​test jednostkowy zawodzi.

Edit2: Oto strona html, jak również funkcja onSave()

HTML:

<div class="container"> 
    <div *ngIf="!waiting" class="row mb-20"> 
     <div class="col-xs-12"> 
      <a class="link-icon" (click)="onClickBack()"> 
       <span class="icon-wmkCaretLeft"></span> 
       <span class="link-text text-uppercase text-condensed">Back</span> 
      </a> 
     </div> 
    </div> 
    <div class="row"> 
     <div class="col-xs-12"> 
      <form *ngIf="(!loadError)" novalidate (ngSubmit)="onSave()"> 
       <template [ngIf]="groupComplete"> 
        <wm-groupinfo-view [groupName]="contractRequest.groupName" [groupId]="contractRequest.groupIdentifier" [subgroupId]="contractRequest.subgroupIdentifier"></wm-groupinfo-view> 
       </template> 
       <template [ngIf]="groupComplete && !effectiveDateComplete"> 
        <member-add-effective-date [componentTitle]="enterEffectiveDateTitle" [effectiveDateString]="dataservice.effectiveDateOfChange" (complete)="onEffectiveDateComplete($event)"></member-add-effective-date> 
       </template> 
       <template [ngIf]="groupComplete && effectiveDateComplete"> 
        <h3 class="text-uppercase">Effective Date</h3> 
        <p><span class="field-label">Effective Date of Change: </span>{{ dataservice.effectiveDateOfChange | wmFixDateFormat }}</p> 
        <div class="buttons"> 
         <button class="btn btn-primary" (click)="onClickEditEffectiveDate()"> 
          <i class="glyphicon glyphicon-edit"></i> 
          Edit Effective Date 
         </button> 
        </div> 
       </template> 
       <template [ngIf]="effectiveDateComplete"> 
        <member-add-subscriber-info [member]="contractRequest.member[0]" [subscriberId]="memberId" (complete)="onSubscriberInfoComplete($event)"></member-add-subscriber-info> 
       </template> 
       <template [ngIf]="subscriberDemoComplete"> 
        <template [ngIf]="!homeAddressInfoComplete"> 
         <member-add-subscriber-address [address]="homeAddressObject" (complete)="onAddressInfoComplete($event)"></member-add-subscriber-address> 
        </template> 
        <template [ngIf]="homeAddressInfoComplete"> 
         <h3 class="text-uppercase">Subscriber Home Address Information</h3> 
         <p *ngIf="dataservice.selectedContract.address[0].type === 'Primary'"><strong>Address Type: </strong>HOME</p> 
         <p *ngIf="dataservice.selectedContract.address[0].type !== 'Primary'"><strong>Address Type: </strong>MAILING</p> 
         <p><strong>Address Line 1: </strong>{{dataservice.selectedContract.address[0].addressLine1}}</p> 
         <p><strong>Address Line 2: </strong>{{dataservice.selectedContract.address[0].addressLine2}}</p> 
         <p><strong>City: </strong>{{dataservice.selectedContract.address[0].city}}</p> 
         <p><strong>State: </strong>{{dataservice.selectedContract.address[0].state}}</p> 
         <p><strong>Zip Code: </strong>{{getZipString(0)}}</p> 
         <p><strong>County: </strong>{{dataservice.selectedContract.address[0].county?.description}}</p> 
         <p><strong>Email: </strong>{{dataservice.selectedContract.address[0].email}}</p> 
         <p><strong>Phone Number: </strong>{{ dataservice.selectedContract.phoneNumber | wmPhonePipe }}</p> 
         <div class="buttons"> 
          <button class="btn btn-primary" (click)="onClickEditAddressInfo()"> 
           <i class="glyphicon glyphicon-edit"></i> 
           Edit Subscriber Home Address 
          </button> 
         </div> 
         <template [ngIf]="!showMailingAddress"> 
          <div class="buttons"> 
           <button class="btn btn-primary" (click)="onClickAddMailingAddressInfo()"> 
            <i class="glyphicon glyphicon-add"></i> 
            Add Subscriber Mailing Address 
           </button> 
          </div> 
         </template> 
         <template [ngIf]="showMailingAddress"> 
          <template [ngIf]="!mailingAddressInfoComplete"> 
           <member-add-subscriber-address [address]="mailingAddressObject" (complete)="onMailingAddressInfoComplete($event)" (delete)="onClickDeleteMailingAddressInfo($event)"></member-add-subscriber-address> 
          </template> 
          <template [ngIf]="mailingAddressInfoComplete"> 
           <h3 class="text-uppercase">Subscriber Mailing Address Information</h3> 
           <p *ngIf="dataservice.selectedContract.address[1].type === 'Primary'"><strong>Address Type: </strong>HOME</p> 
           <p *ngIf="dataservice.selectedContract.address[1].type !== 'Primary'"><strong>Address Type: </strong>MAILING</p> 
           <p><strong>Address Line 1: </strong>{{dataservice.selectedContract.address[1].addressLine1}}</p> 
           <p><strong>Address Line 2: </strong>{{dataservice.selectedContract.address[1].addressLine2}}</p> 
           <p><strong>City: </strong>{{dataservice.selectedContract.address[1].city}}</p> 
           <p><strong>State: </strong>{{dataservice.selectedContract.address[1].state}}</p> 
           <p><strong>Zip Code: </strong>{{dataservice.selectedContract.address[1].zip}}</p> 
           <p><strong>County: </strong>{{dataservice.selectedContract.address[1].county?.description}}</p> 
           <div class="buttons"> 
            <button class="btn btn-primary" (click)="onClickEditMailingAddressInfo()"> 
             <i class="glyphicon glyphicon-edit"></i> 
             Edit Subscriber Mailing Address 
            </button> 
            <button class="btn btn-primary" (click)="onClickDeleteMailingAddressInfo()"> 
             <i class="glyphicon glyphicon-edit"></i> 
             Delete Subscriber Mailing Address 
            </button> 
           </div> 
          </template> 
         </template> 
        </template> 
       </template> 
       <ng-container *ngIf="subscriberDemoComplete && homeAddressInfoComplete && (!showMailingAddress || mailingAddressInfoComplete)"> 
        <member-add-dependent *ngIf="addingDependents" [member]="dependent" [editing]="isEditingDependent" (complete)="onDependentComplete($event)"></member-add-dependent> 
        <div *ngIf="dependentComplete"> 
         <h3 class="text-uppercase">Dependent/Member Information</h3> 
         <p><strong>Relationship: </strong>{{ dataservice.getRelationshipString(dependent.relationship) }}</p> 
         <p><strong>First Name: </strong>{{dependent.firstName}}</p> 
         <p><strong>Middle Initial: </strong>{{dependent.middleInitial}}</p> 
         <p><strong>Last Name: </strong>{{dependent.lastName}}</p> 
         <p><strong>Title: </strong>{{dependent.title}}</p> 
         <p><strong>Date of Birth: </strong>{{ dependent.birthDt | wmFixDateFormat }}</p> 
         <p><strong>Social Security Number: </strong>{{dependent.ssn}}</p> 
         <p><strong>Gender: </strong>{{dependent.sex}}</p> 
         <p><strong>Marital Status: </strong>{{dependent.maritalStatus}}</p> 
         <p><strong>Original Effective Date: </strong>{{dependent.originalEffectiveDt | wmFixDateFormat}}</p> 
         <div class="buttons"> 
          <button class="btn btn-primary" (click)="onClickEditDependentDemo(dependent)"> 
           <i class="glyphicon glyphicon-edit"></i> 
           Edit Dependent Information 
          </button> 
         </div> 
        </div> 
       </ng-container> 
       <ng-container *ngIf="showProducts && dependentComplete"> 
        <member-add-products [members]="contractRequest.member" [addingMember]="true" (complete)="onProductsComplete($event)"></member-add-products> 
       </ng-container> 
       <div> 
        <wm-error-list [errors]="errorList" (clickError)="focusField($event)" (addError)="errorAdded($event)"></wm-error-list> 
       </div> 
       <div *ngIf="(!waiting)" class="buttons pb-10"> 
        <div *ngIf="canSave()"> 
         <button id="saveButton" class="btn btn-primary pull-right" type="submit">Add&nbsp;Member</button> 
        </div> 
        <div *ngIf="!canSave()"> 
         <button [disabled]="true" class="btn btn-primary pull-right">Add&nbsp;Member</button> 
        </div> 
        <button class="btn btn-secondary pull-right" type="button" (click)="onClickCancel()">Cancel</button> 
       </div> 
       <div *ngIf="(waiting)"> 
        <wm-spinner></wm-spinner> 
       </div> 
      </form> 
      <div *ngIf="(loadError)"> 
       <h3>{{errorMessage}}</h3> 
      </div> 
     </div> 
    </div> 
</div> 

onSave():

onSave() { 
    if (event.defaultPrevented || this.waiting) { 
     return; 
    } 

    this.clearErrors(); 
    this.checkErrors(); 

    if (this.hasErrors() || (!this.unitTesting && !confirm("You are about to add this member. Are you sure you want to continue?"))) { 
     return; 
    } 

    this.waiting = true; 

    this.saveUpdatedSubscriberInformation(); 

    var addMemberObject = this.buildAddMemberObject(); 

    this.contractsService.addMember(addMemberObject) 
     .subscribe(response => { 
      this.parseAddMemberResponse(response, addMemberObject, true); 
      //only save the note on success of adding member 
      this.saveNote(); 
     }, error => { 
      this.parseAddMemberResponse(error, addMemberObject, false); 
     }); 
} 
+1

można podać plunker? – yurzui

+0

html formularza i kodu onSubmit, mogłoby być pomocne – valorkin

+0

@valorkin Zaktualizowałem pytanie za pomocą kodu html i onSave. – ganders

Odpowiedz

0

got to działa chwilę temu, ale zapomniałem zaktualizować SO pytanie ...

Wszystko, co potrzebne do zrobienia było stworzenie obojętnego obiektu "zdarzenia" na moim komponencie, a następnie jawne ustawienie niektórych wartości w teście przed uruchomieniem wszystkiego. Kiedy to się stało, wszystko działało dobrze.

Więc, robiąc coś takiego mogło pracował w składzie:

if (event && event.preventDefault) { event.preventDefault(); } 

Albo to mogło być zrobione w teście:

component.event = { preventDefault: function() {} }; 
0

Jeśli chcesz zapobiec wydarzenie będziesz musiał dodać wydarzenie do swojej funkcji onSave, więc zamień ją na nową, więc wymień

<form *ngIf="(!loadError)" novalidate (ngSubmit)="onSave()"> 

z

<form #myForm="ngForm" *ngIf="(!loadError)" novalidate (ngSubmit)="onSave(myForm, $event)"> 

i dodać parametry do OnSave funkcji

public onSave(myForm: any, event: Event) { 
    event.preventDefault(); // or event.defaultPrevented to check 
    .... rest of your code 
}