首页 文章

在分层结构中解决角度为4的单元测试用例中的依赖性

提问于
浏览
0

我是角色的新手,并为我的项目工作单元测试案例 . 我经历了一些不知情的事情Unit Testing

在我尝试为我的项目编写单元测试用例时阅读这些文章后,我无法解决我的测试用例中的依赖性 . 由于我有一个分层结构,并且当我在我的测试用例中注入依赖项时,而这些测试用例又调用了其他层,因此依赖关系无法解析 . 我无法找到如何解决执行测试用例的依赖项 .

我有一个LoginComponent类,一个AuthService类和一个HttpService类

import { Component, OnInit } from '@angular/core';
import {Router} from '@angular/router';
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
import { HttpService } from '../../common/services/http.service';
import {LocalStorageService} from '../../common/services/local-storage.service';
import { AuthService } from '../../common/services/auth.service';
import {PathConfig} from '../../common/config/path.config';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-user-login',
  styleUrls: ['./login.component.scss'],
  templateUrl: './login.component.html'
})
export class LoginComponent implements OnInit {
  public loginForm: FormGroup;
  public submitted: boolean;

  constructor(private router: Router, 
              private httpService: HttpService,
              private localStorageService: LocalStorageService,
              private authService: AuthService,
              private toastr: ToastrService) {}

  ngOnInit () {
    this.loginForm = new FormGroup({
      name: new FormControl('testmarion', [Validators.required]),
      pwd: new FormControl('testmarion', [Validators.required])
    });
  }

  doLogin(value: any, isValid: boolean ) {
    if (isValid) {
      this.authService.login(PathConfig.LOGIN, value)
      .then((data:any)=> {
           this.localStorageService.set("userInfo",JSON.stringify(data.response));
           this.localStorageService.set("AuthToken",data.response.AccessToken);
           this.router.navigate(['/home']);
      }).
      catch(err => {
        this.toastr.error(err.message);
  });

    }
  }
}
import { Injectable }     from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {LocalStorageService} from "./local-storage.service";
import {ConstantConfig} from "../config/constant.config";
import {HttpHeaders} from "@angular/common/http";

@Injectable()

@Injectable()
export class AuthService {
    constructor ( private http:HttpClient , private localStorage:LocalStorageService) {}
    //Auth REQUEST
    login(url,obj: Object): Promise<any>{
      let body = JSON.stringify(obj); 
       let modifyUrl = url +'?userName='+obj['name']+'&'+'password='+obj['pwd'];
        return this.http.get(modifyUrl)
        .toPromise()
        .then((res:any) => {
          console.log(res);
         return ({'response':res})
        }).catch((error:any) => { return Promise.reject( error || 'Server error')}  )
    }

    //check login status
   isLoggedIn():boolean{
       var data = this.localStorage.get(ConstantConfig.AUTH_TOKEN);
       return data ? true : false ;
   }
}
import {Injectable, Inject}     from '@angular/core';
import {HttpClient, HttpParams} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

import {LocalStorageService} from "./local-storage.service";
import {ConstantConfig} from "../config/constant.config";

@Injectable()
export class HttpService {
  // Resolve HTTP using the constructor
  constructor (private http: HttpClient ,@Inject(LocalStorageService)private localStorage:LocalStorageService) {}

  // GET REQUEST
  get(url) : Observable<any>{

    // Create a request option
    let options = {
      headers: {
        'Content-Type':'application/json',
         'Authorization': this.localStorage.get(ConstantConfig.AUTH_TOKEN)
      },

    };

    //using get request
   // return this.http.get(url,options)
   return this.http.get(url)
    // and calling .json() on the response to return data
      .map((res:any) => res ).catch((err:any) => Observable.throw(err['error'] || err || 'Server error'))

  }

  //POST REQUEST
  post(url,obj: Object): Observable<any> {
      let body    = obj
      let options = { headers: {
          'Content-Type':'application/json',
          'Authorization': this.localStorage.get(ConstantConfig.AUTH_TOKEN)
      } }; // Create a request option

    //using post request
    return this.http.post(url, body, options) //using post request
      .map((res:any) => res ) //and calling .json() on the response to return data
      .catch((err:any) =>  Observable.throw(err['error'] || err || 'Server error')); //errors if any
  }


}

组件类中的doLogin函数调用AuthService类中的login函数,该类调用httpservice的get方法来进行api命中 .

我正在尝试为doLogin函数创建单元测试用例 . 对于这个在login.component.spec.ts文件中我尝试的是通过在构造函数中注入依赖项来创建一个登录组件的实例现在当我在我的单元测试中用我的对象调用doLogin函数时我得到了无法调用Login函数的错误未定义的 . 同样的情况是我使用TestBed .

我无法弄清楚如何解决服务的依赖关系 .

1 回答

  • 0

    你必须嘲笑你的组件 .

    例如,这就是你嘲笑服务的方式:

    const authMock = {
      login: () => Promise.resolve(true),
      isLoggedIn: () => true
    };
    
    TestBed.configureTestingModule({
      declarations: [AppComponent],
      providers: [
        { provide: AuthService, useValue: authMock }
      ]
    }).compileComponents();
    

    authMock 变量中,您需要将每个函数,每个变量都放在服务中 . 这样,当您的测试组件调用该服务时,它实际上会调用您的模拟 .

    然后您可以像这样模拟返回:

    it('should call the service if the form is valid', () => {
      spyOn(component['authService'], login).and.returnValue(Promise.resolve({data: 'anything you want there'}));
    
      component.doLogin('value', true);
    
      expect(component['authService'].login).toHaveBeenCalledWith(PathConfig.LOGIN, 'value');
    });
    

相关问题