1

我正在尝试为我创建的登录组件创建一个测试,但每次运行测试时都会出现以下错误。

Error: Can't resolve all parameters for Router: (?, ?, ?, ?, ?, ?, ?, ?).

我很确定我做错了什么,因为我基于几个在线教程创建了登录组件/服务,而我对 Angular 的了解非常有限,无法理解我做错了什么。谁能给我一个关于我做错了什么的建议......或者指向一个教程,其中包含一个经过测试的实际服务被调用?我尝试了 Auth0 tuts ......来自这里的那些,但那些也不适合我。

不知何故,登录正在工作,我可以正常使用它。

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map'
import { Settings } from './app.settings.model';
import { AppSettings } from './app.settings';
import { Router } from '@angular/router';
import { ToastrService } from 'ngx-toastr';

@Injectable()
export class AuthService {

public isAuthenticated: boolean = false;

public settings: Settings;

constructor(public appSettings:AppSettings,private http: HttpClient, private router: Router,public toastr: ToastrService) {
  this.settings = this.appSettings.settings;
 }
// store the URL so we can redirect after logging in

redirectUrl: string;

    login(username: string, password: string) {

      let encodedData = window.btoa(username + ':' + password );

      return this.http.post('https://localhost:8000/rest/login', {username: username, password: password}, {
        headers: new HttpHeaders().set('Authorization', 'Basic ' + encodedData)
    })
            .map(user => {
              this.isAuthenticated =  true;
              localStorage.setItem('LOGIN', encodedData);
              this.router.navigate(['/schedule']);
              this.toastr.success('Authentication successful!');
               return user;
            });
    }

    logout(): void {
      this.router.navigate(['/login']);
      localStorage.removeItem('LOGIN');
  }
}

这是我的登录组件

import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormGroup, FormBuilder, Validators} from '@angular/forms';
import { AppSettings } from '../../app.settings';
import { Settings } from '../../app.settings.model';
import { AuthService }  from '../../auth.service';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html'
})
export class LoginComponent {
  public form:FormGroup;
  public settings: Settings;
  returnUrl: string;

  model: any = {};

  constructor(
    public appSettings:AppSettings, 
    public fb: FormBuilder, 
    public authService: AuthService,
    private route: ActivatedRoute,
    public router:Router,
    public toastr: ToastrService)
  {
    this.settings = this.appSettings.settings;
    this.form = this.fb.group({
      username: [null, Validators.compose([Validators.required])],
      password: [null, Validators.compose([Validators.required])] 
    });
  }

  @Input()
  username: string;

  @Output()
  submitted = new EventEmitter();

  login(username, password) {
    this.authService.login(username, password)
        .subscribe(
            data => {
               this.settings.loadingSpinner = true; 
                this.router.navigate([this.returnUrl]);
            },
            error => {
              console.log(error);
              this.toastr.error("Authentication failed");
              this.settings.loadingSpinner = false; 
            });
} 


  public onSubmit(values:Object):void {
    if (this.form.valid) {
      let user = this.form.value.username;
      let pass = this.form.value.password;
      this.settings.loadingSpinner = true; 
      this.submitted.emit({user,pass});
      this.login(this.form.value.username, this.form.value.password);
       }
  }


  logout() {
    this.authService.logout();
  }

  ngOnInit(){
    this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
  }

  ngAfterViewInit(){
    this.settings.loadingSpinner = false; 
  }
}

这是我的测试:

import { TestBed, async, inject } from '@angular/core/testing';
import { HttpClientModule, HttpRequest, HttpParams } from @angular/common/http';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { AuthService } from '../../auth.service';
import { AppSettings } from '../../app.settings';
import { Router } from '@angular/router';


describe(`AuthService`, () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientModule,
        HttpClientTestingModule
      ],
      providers: [
        AuthService, AppSettings, Router
      ]
    });
  });

  afterEach(inject([HttpTestingController], (backend: HttpTestingController) => {
    backend.verify();
  }));

  it(`should send an expected login request`, async(inject([AuthService, HttpTestingController],
    (service: AuthService, backend: HttpTestingController) => {
      service.login('gaia', 'gaia');
      backend.expectOne((req: HttpRequest<any>) => {
        const body = new HttpParams({ fromString: req.body });
        return req.url === 'auth/login'
          && req.method === 'POST'
          && req.headers.get('Content-Type') === 'application/x-www-form-urlencoded'
      }, `POST to 'auth/login' with form-encoded user and password`);
  })));

      it(`should emit 'false' for 401 Unauthorized`, async(inject([AuthService, HttpTestingController],
        (service: AuthService, backend: HttpTestingController) => {
          service.login('foo', 'bar').subscribe((next) => {
            expect(next).toBeFalsy();
          });

          backend.expectOne('auth/login').flush(null, { status: 401, statusText: 'Unauthorized' });
      })));

      it(`should emit 'true' for 200 Ok`, async(inject([AuthService, HttpTestingController],
        (service: Au

thService, backend: HttpTestingController) => {
      service.login('foo', 'bar').subscribe((next) => {
        expect(next).toBeTruthy();
      });

      backend.expectOne('auth/login').flush(null, { status: 200, statusText: 'Ok' });
  })));

});
4

2 回答 2

0

我认为您需要RouterTestingModule在您的 Testbed 配置中导入

于 2018-04-11T09:00:40.650 回答
0

在您的测试中,您必须模拟您的路线服务:

在导入之后,输入:

class MockRouter {
  navigate = jasmine.createSpy('navigate');
}

然后编辑您的路由器提供商以使用模拟

beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [...],
      providers: [
        ...
        {provide: Router, useClass: MockRouter}
      ]
    });
  });

它应该可以解决问题

于 2018-07-04T09:29:37.620 回答