在Angular测试中模拟gauth attachClickHandler

问题描述 投票:-1回答:1

我在模拟gauth的attachClickHandler函数时遇到问题。以下是我的代码。我无法模拟attachClickHander onSuccess和onFailure回调。因此,无法测试prepareLoginButton方法。

export class GoogleSignInButtonComponent implements OnInit {

  auth2: any;

  constructor(
    private socialSignInController: SocialSignInControllerService,
    private ngZone: NgZone,
    private toastr: ToastrService,
    private authenticationService: AuthenticationService) { }

  ngOnInit(): void {
    this.googleSDK();
  }
  googleSDK() {

    window['googleSDKLoaded'] = () => {
      window['gapi'].load('auth2', () => {
        this.auth2 = window['gapi'].auth2.init({
          client_id: environment.social.google.clientId,
          cookiepolicy: 'single_host_origin',
          scope: 'profile email'
        });
        this.prepareLoginButton();
      });
    }

    (function (d, s, id) {
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) { return; }
      js = d.createElement(s); js.id = id;
      js.src = "https://apis.google.com/js/platform.js?onload=googleSDKLoaded";
      fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'google-jssdk'));

  }

   prepareLoginButton() {
    this.auth2.attachClickHandler(document.getElementById('googleBtn'), {},
      (googleUser) => {
        this.ngZone.run(() => {
          const token = googleUser.getAuthResponse().id_token;
          this.socialSignInController.googleTokenSignIn(token).subscribe(res => {
            this.authenticationService.onSocialLoginSuccess(res.token);
            window.location.href = '/dashboard'
          });
        }, (error) => {
          this.toastr.error('An error occurred. Please try again', 'Could not sign you in')
          console.log(error);
        });
      })

  }

}
angular jasmine google-authentication
1个回答
0
投票

目标是实施google登录。并且该代码需要100%的测试。由于很难模拟auth2 attachClickHandler成功函数,因此我删除了该函数并使用了库angularx-social-login link to GitHub repo

我创建了CustomHRefService,因为router.navigate无法正常工作,然后在promise中起作用。后来我发现,将希望变为可观察的承诺解决了这一问题。

代码和测试如下:

The Button html

<a #googlebtn (click)="signInWithGoogle()" class="social_bt google" id="googleBtn">Login with google</a>

The Button Ts

import { Component, OnInit, Inject } from '@angular/core';
import { AuthService, GoogleLoginProvider } from 'angularx-social-login';
import { SocialSignInControllerService } from 'dd-core-api-sdk';
import { CustomHrefService } from 'src/app/services/custom-href.service';

@Component({
  selector: 'app-google-btn',
  templateUrl: './google-btn.component.html',
  styleUrls: ['./google-btn.component.css'],
})
export class GoogleBtnComponent implements OnInit {

  constructor(private authService: AuthService,
    private socialSignInController: SocialSignInControllerService,
    private authenticationService: AuthenticationService,
    private customeHref: CustomHrefService
  ) { }

  ngOnInit(): void {
  }

  signInWithGoogle(): void {
    this.authService.signIn(GoogleLoginProvider.PROVIDER_ID).then(googleUser => {
      this.socialSignInController.googleTokenSignIn({ token: googleUser.idToken }).subscribe(res => {
        this.authenticationService.onSocialLoginSuccess(res.token);
        this.customeHref.jumpTo('/dashboard')

      })
    })
  }

}

按钮测试

import { async, ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing';

import { GoogleBtnComponent } from './google-btn.component';
import { provideConfig } from '../authentication.module';
import { AuthenticationServiceImpl } from 'src/app/services/authentication.service';
import { AuthService, AuthServiceConfig, SocialUser } from 'angularx-social-login';
import { of } from 'rxjs';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { ToastrModule } from 'ngx-toastr';
import { CustomHrefService } from 'src/app/services/custom-href.service';
import { WindowToken } from 'src/app/injector/window';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';

const MockWindow = {
  location: {
    _href: '',
    set href(url: string) { this._href = url },
    get href() { return this._href }
  }
};

describe('GoogleBtnComponent', () => {
  let component: GoogleBtnComponent;
  let fixture: ComponentFixture<GoogleBtnComponent>;
  let authService: AuthService;
  let socialSignInService: SocialSignInControllerService;
  let socialSignInSpy: jasmine.Spy;
  let authSpy: jasmine.Spy;
  let service: CustomHrefService;
  let setHrefSpy: jasmine.Spy;

  beforeEach(async(() => {

    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule,
        RouterTestingModule.withRoutes([{ path: 'dashboard', component: DummyComponent }]),
        ToastrModule.forRoot(),
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useValue: new FakeLoader()
          }
        }),
      ],

      declarations: [GoogleBtnComponent],
      providers: [{
        provide: AuthenticationService,
        useClass: AuthenticationServiceImpl,
      }, AuthService, { provide: AuthServiceConfig, useFactory: provideConfig },
      { provide: CustomHrefService, useClass: CustomHrefService, deps: [WindowToken]},
      { provide: WindowToken, useValue: MockWindow }]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    //mock response
    socialSignInService = TestBed.get(SocialSignInControllerService);
    service = TestBed.get(CustomHrefService);
    authService = TestBed.get(AuthService);
    socialSignInSpy = spyOn(socialSignInService, "googleTokenSignIn").and.returnValue(of({ token: '2323' } as any))
    setHrefSpy = spyOnProperty(MockWindow.location, 'href', 'set');
    const googleUser: SocialUser = {
      name: 'godwin', firstName: 'ish',
      lastName: 'dako', idToken: '1009',
      provider: 'google',
      id: '2', email: '[email protected]',
      photoUrl: 'null',
      authToken: '2323', authorizationCode: '232'
    };
    authSpy = spyOn(authService, 'signIn').and.returnValue(Promise.resolve(googleUser));
    fixture = TestBed.createComponent(GoogleBtnComponent);
    authService = TestBed.get(AuthService);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

  it('should sign with google', fakeAsync(() => {
    component.signInWithGoogle();
    fixture.detectChanges();
    tick(3);
    expect(setHrefSpy).toHaveBeenCalledWith('/dashboard');
  }))


});

CustomHrefService

import { Injectable, Inject } from '@angular/core';
import { WindowToken } from '../injector/window';

@Injectable({
  providedIn: 'root'
})
export class CustomHrefService {

  constructor(@Inject(WindowToken) private window: Window) {}

  jumpTo(url: string) {
    this.window.location.href = url;
  }}

WindowToken

import { InjectionToken } from '@angular/core';

export const WindowToken = new InjectionToken('Window');
export function windowProvider() { return window; }

使用InjectionToken

@NgModule({
  declarations: [
    //components],
  imports: [
    //other modules
  ],
  providers: [{
    { provide: WindowToken, useFactory: windowProvider }
  ]
})
export class AuthenticationModule { }

CustomHrefService测试

import { TestBed } from '@angular/core/testing';

import { CustomHrefService } from './custom-href.service';
import { Injector } from '@angular/core';
import { WindowToken } from '../injector/window';
import { AuthenticationModule } from '../modules/authentication/authentication.module';

const MockWindow = {
  location: {
    _href: '',
    set href(url: string) { this._href = url },
    get href() { return this._href }
  }
};

describe('CustomHrefService', () => {
  let service: CustomHrefService;
  let setHrefSpy: jasmine.Spy;


  beforeEach(() => {
    setHrefSpy = spyOnProperty(MockWindow.location, 'href', 'set');
    const injector = Injector.create({
      providers: [
        { provide: CustomHrefService, useClass: CustomHrefService, deps: [WindowToken]},
        { provide: WindowToken, useValue: MockWindow}
      ]
    });
    service = injector.get(CustomHrefService);
  });

  it('should be registered on the AppModule', () => {
    service = TestBed.configureTestingModule({ imports: [AuthenticationModule] }).get(CustomHrefService);
    expect(service).toEqual(jasmine.any(CustomHrefService));
  });

  describe('#jumpTo', () => {
    it('should modify window.location.href', () => {
      const url = 'http://localhost:8080';
      service.jumpTo(url);
      expect(setHrefSpy).toHaveBeenCalledWith(url);
    });
  });
});
© www.soinside.com 2019 - 2024. All rights reserved.