Angular 7: How to access/send only body part of HTTP Response from test case

Viewed 647

I'm creating unit test cases in Angular 7 for a Component with async service.

here is my component file :

  submitLoginForm() {
    if (this.loginForm.valid) {
      // send a http request to save this data
      this.guestUserService.login(this.loginForm.value).subscribe(
        result => {
          // if (result) {
          if (result['token']) { // The value of result is coming the complete HttpResponse. 
            localStorage.setItem('authToken', result['token']);
            this.router.navigate(['/dashboard']);
          }
        },
        error => {
          console.log('error', error.message);
          this.router.navigate(['/error']);
        }
      );
    } else {
      this.validateAllFields(this.loginForm);
    }
  }

}

the unit test case:

fdescribe('LoginComponent', () => {
    let component: LoginComponent;
    let fixture: ComponentFixture<LoginComponent>;
    let guestUserService: any;
    let guestUserServiceSpy: any;

    beforeEach(async(() => {
        guestUserService = jasmine.createSpyObj('GuestUserService', ['login']);

        TestBed.configureTestingModule({
            declarations: [LoginComponent, ErrorComponent, RegistrationComponent],
            imports: [
                ReactiveFormsModule,
                FormsModule,
                RouterTestingModule,
                HttpClientModule,
                AppRoutingModule,
            ],
            providers: [
                { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
                { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
                { provide: APP_BASE_HREF, useValue: '/' },
                { provide: GuestUserService, useValue: guestUserService }]
        })
            .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(LoginComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

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

  it('should Successfully Submit Registration Form', async(inject([Router], (router) => {
        guestUserServiceSpy = guestUserService.login.and.returnValue(of(new HttpResponse({ status: 200, body: { result: { token: 'DummyTokenIsSent' } } })));

        spyOn(router, 'navigate');
        spyOn(component, 'submitLoginForm').and.callThrough();

        component.loginForm.controls['username'].setValue('hasnani@vishal.com');
        component.loginForm.controls['password'].setValue('12345678');

        component.submitLoginForm();

        expect(component.submitLoginForm).toHaveBeenCalled();
        expect(component.loginForm.invalid).toBe(false);

        expect(guestUserService).toBeDefined();
        expect(guestUserServiceSpy).toBeDefined();
        expect(guestUserServiceSpy).toHaveBeenCalledTimes(1);
        expect(router.navigate).toHaveBeenCalled();
        expect(router.navigate).toHaveBeenCalledWith(['/dashboard']);
    })
    ));

The value of result while running the test case:

enter image description here

I found that the error is coming as the code is not going through this part "if (result['token'])" But how to access or send body part of the http response form unit test case without effecting the component part.

1 Answers

use HttpClientTestingModule as import and mock your http response:

httpMock = injector.get(HttpTestingController);
const req = httpMock.expectOne(`path`);
expect(req.request.method).toBe("GET");
req.flush({fakeresponse:true);
Related