Как смоделировать значение объекта конфигурации, используемого в конструкторе, с помощью Jasmine - PullRequest
0 голосов
/ 27 сентября 2019

Я недавно начал использовать Jasmine для тестирования приложения Angular, и, хотя большинство тестов работают нормально, у меня возникают проблемы с определенным.

Так что это тест для AppComponent, которыйвыглядит следующим образом:

app.component.ts

import { Component, OnDestroy } from '@angular/core';
import { Idle, DEFAULT_INTERRUPTSOURCES } from 'ng2-idle-core';
import { Store } from '@ngxs/store';

import { OAuthService, JwksValidationHandler } from 'angular-oauth2-oidc';

import {
    authConfig,
    LoginSuccess,
    CriticalErrorHandler,
    CriticalLogoutRequest } from './core';

@Component({
    selector: 'my-app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent {
    idleState = 'Not started.';
    timedOut = false;
    lastPing?: Date = null;

    // Important to keep the "CriticalErrorHandler" here, because it is an injectable "service" and must be
    // instancied at the beginning of the app
    constructor(
        private idle: Idle,
        private store: Store,
        private criticalErrorHandler: CriticalErrorHandler,
        private oauthService: OAuthService) {

        // Idle time
        this.idle.setIdle(3600);

        this.idle.setTimeout(30);

        this.idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);

        this.idle.onIdleStart.subscribe(() => {
          this.store.dispatch(new CriticalLogoutRequest());
        });

        this.login();
    }

    private login() {
        this.oauthService.configure(authConfig);
        this.oauthService.tokenValidationHandler = new JwksValidationHandler();

        this.oauthService.loadDiscoveryDocumentAndLogin({
            onTokenReceived : () => {
                this.oauthService.setupAutomaticSilentRefresh();
                this.store.dispatch(new LoginSuccess());
            }
        });
    }
}

Как видно, конструктор вызывает функцию login (), которая в свою очередь использует конфигурациюобъект с именем authConfig выглядит следующим образом:

auth.config.ts

import { AuthConfig } from "angular-oauth2-oidc";
import { environment } from "environments/environment";

export const authConfig: AuthConfig = {

  silentRefreshRedirectUri : window.location.origin + '/assets/silent-refresh.html',

  issuer: environment.endpoints.identity,

  redirectUri: window.location.origin + '/index.html',

  clientId: 'ID',

  scope: 'openid user permissions My.WebApp',

  responseType: "id_token token",

  requireHttps: environment.requireHttps,

  sessionChecksEnabled : true

};

Это вызывает другой объект конфигурации с именем environment, для которого requireHttps имеет значение true.Поэтому, когда я делаю простой тест создания, как это:

app.component.spec.ts

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, TestBed, ComponentFixture } from '@angular/core/testing';
import { RouterModule } from '@angular/router';
import { SharedModule } from 'primeng/primeng';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';

fdescribe('AppComponent', () => {
    let component: AppComponent;
    let fixture: ComponentFixture<AppComponent>;

    beforeEach(async(() => {

        TestBed.configureTestingModule({
            imports: [
                CoreModule,
                SharedModule,
                RouterModule.forRoot([])
            ],
            declarations: [AppComponent],
            schemas: [CUSTOM_ELEMENTS_SCHEMA]
        }).compileComponents();
    }));

    it('should create the app', async(() => {

        fixture = TestBed.createComponent(AppComponent);
        component = fixture.componentInstance;
        expect(component).toBeTruthy();
    }));

});

Я получаю "эмитент должен использовать httpsили значение конфигурации для свойства requireHttps должно разрешать http ".Итак, что я хочу сделать, это изменить для свойства теста свойство requireHttps объекта config на false.Но я не совсем уверен, как это сделать ... любая помощь приветствуется!

1 Ответ

1 голос
/ 28 сентября 2019

Что если бы вы вместо этого передали AuthConfig в качестве аргумента для login() вашего компонента?Это позволит вам снова смоделировать ваш AuthConfig в модульном тесте.

app.component.ts

import { authConfig } from './core';
...
this.login(authConfig);
...

private login(_authConfig:AuthConfig) {
    this.oauthService.configure(_authConfig);
    this.oauthService.tokenValidationHandler = new JwksValidationHandler();

    this.oauthService.loadDiscoveryDocumentAndLogin({
        onTokenReceived : () => {             
            this.oauthService.setupAutomaticSilentRefresh();
            this.store.dispatch(new LoginSuccess());
        }
    });
}

И в вашем наборе тестов вы будетебыть насмешливым (создавая его новый экземпляр ради этого теста) AuthConfig объект

app.component.spec.ts


beforeEach(() => async(() => {
   ...
   let mockAuthConfig: AuthConfig;
   ...
}))

beforeEach(() => {
   ...
   mockAuthConfig = {
      silentRefreshRedirectUri : window.location.origin + '/assets/silent-refresh.html',
      issuer: environment.endpoints.identity,
      redirectUri: window.location.origin + '/index.html',
      clientId: 'ID',
      scope: 'openid user permissions My.WebApp',
      responseType: "id_token token",
      requireHttps: false, // <== CHANGED
      sessionChecksEnabled : true
   }
   ...

   fixture.detectChanges();
})

...

it(`testing login()`, fakeAsync(() => {
   component.login(mockAuthConfig);

   //your tests here
   //expect(...).toBe(...);
}))

По существу, вызов login () в app.component.ts будет использовать authConfig, который вы предварительно определили и экспортировали.Тем не менее, в вашем модульном тестовом примере вы будете издеваться (воссоздавать) новый AuthConfig объект, который имеет другие свойства, которые вы затем передаете в login() через component.login(mockAuthConfig).

Надеюсь, что это работает для вас!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...