【问题标题】:Spyon with returnValue() execute original function but no desired value带有 returnValue() 的间谍执行原始函数但没有所需的值
【发布时间】:2022-01-26 03:12:13
【问题描述】:

开发人员您好,我一直在做一些单元测试教程,但是当我对组件内的函数进行测试时,尝试对 http 调用示例执行 UT 时遇到问题,它返回函数的原始值,但没有我希望它返回的值做 spyOn(x,x).and.returnValue(X) 有人可以帮助我吗?

这是我的组件

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { environment } from '../../../environments/environment';

@Component({
 selector: 'app-root',
 templateUrl: './entrega.component.html',
 styleUrls: ['./entrega.component.css']
})
export class EntregaComponent implements OnInit {
 idEntrega:any='';
 foto:any='';
 urlCasillero='';
 constructor(private route: ActivatedRoute) { }

 ngOnInit() {
  
   this.urlCasillero=environment.URLCASILLERO;
   this.idEntrega = this.route.snapshot.params.id;
 }


 peticionFoto(data:string):string{
   let foto:string='';
   
     fetch(this.urlCasillero+this.idEntrega).then(res => res.text()).then((text:string) => {
       this.foto=text;
   })
   
 return foto;
 }


}

这是我的 .specs 文件

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; 


import { EntregaComponent } from './entrega.component';

describe('EntregaComponent', () => {
  let component: EntregaComponent;
  let fixture: ComponentFixture<EntregaComponent>;


  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ EntregaComponent ],
      imports: [ RouterTestingModule  ],
    })
    .compileComponents();
  });

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

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


  it('debe obtener una foto', () => {
    spyOn(component,"peticionFoto").and.returnValue(
      "foto"
    );
      expect(component.foto).toBe('foto');
    });

    
 
});

这是我对 ng 测试的茉莉花结果


EntregaComponent > debe obtener una foto

Expected '' to be 'foto'.

Error: Expected '' to be 'foto'.
    at <Jasmine>
    at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/pages/entrega/entrega.component.spec.ts:36:30)
    at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/fesm2015/zone.js:372:1)
    at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/fesm2015/zone-testing.js:287:1)

【问题讨论】:

    标签: angular unit-testing jasmine karma-runner


    【解决方案1】:

    您什么也不做或没有显式调用函数来定义foto。此外,return foto 仅在我们将此函数调用分配给变量时才有意义。

    我会做出以下改变。

    我会使用 HttpClient 而不是 fetch,Angular 为我们提供了这个 HttpClient 来简化单元测试。

    import { Component, OnInit } from '@angular/core';
    import { ActivatedRoute } from '@angular/router';
    import { environment } from '../../../environments/environment';
    
    @Component({
     selector: 'app-root',
     templateUrl: './entrega.component.html',
     styleUrls: ['./entrega.component.css']
    })
    export class EntregaComponent implements OnInit {
     idEntrega:any='';
     foto:any='';
     urlCasillero='';
     constructor(private route: ActivatedRoute, private http: HttpClient) { }
    
     ngOnInit() {
       this.urlCasillero=environment.URLCASILLERO;
       this.idEntrega = this.route.snapshot.params.id;
     }
    
    
     peticionFoto(data:string): void {
       this.httpClient.get(this.urlCasillero+this.idEntrega).pipe(
         // might not be needed, this map
         map(res => res.text()),
       ).subscribe(result => {
         console.log(result); // make sure the result is what you would like
         this.foto = result;
       });
     }
    }
    

    对于测试:

    import { EntregaComponent } from './entrega.component';
    
    describe('EntregaComponent', () => {
      let component: EntregaComponent;
      let fixture: ComponentFixture<EntregaComponent>;
      let httpTestingController: HttpTestingController;
    
    
      beforeEach(async () => {
        await TestBed.configureTestingModule({
          declarations: [ EntregaComponent ],
          // !! Add HttpClientTestingModule !!
          imports: [ RouterTestingModule, HttpClientTestingModule  ],
        })
        .compileComponents();
      });
    
      beforeEach(() => {
        // get an instance of http testing controller
        httpTestingController = TestBed.inject(HttpTestingController);
        fixture = TestBed.createComponent(EntregaComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
      });
    
      it('should create', () => {
        expect(component).toBeTruthy();
      });
    
    
      it('debe obtener una foto', fakeAsync(() => {
       // call the function
       component.peticionFoto('abc');
       // expect a get request   
       const request = httpTestingController.expectOne(request => request.method === 'GET');
       // flush this response
       request.flush({ text: () => 'abc' });
       // wait for subscriptions to complete   
       tick();
       expect(component.foto).toBe('abc');
      }));
     
    });
    

    我在没有 IDE 的情况下做了所有事情,所以可能会出现错误。话虽如此,我发现这个资源https://testing-angular.com/ 非常适合学习单元测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-17
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 2020-07-21
      • 1970-01-01
      • 2013-12-03
      • 1970-01-01
      相关资源
      最近更新 更多