【问题标题】:Unit testing a Service method subscribed to an Observable in Angular在 Angular 中对订阅 Observable 的 Service 方法进行单元测试
【发布时间】:2017-02-15 22:43:14
【问题描述】:

我想用 Jasmine 测试这个组件:

export class EditorComponent implements OnInit {
  movimiento: Movimiento;

  constructor(private route: ActivatedRoute, private datosService: DatosService) { }

  ngOnInit() {
    this.route.params
      .subscribe(params => {
        const _id = params['id'].toString(); // recepción del parámetro
        this.datosService
          .getMovimientoBy_Id$(_id)
          .subscribe(r => this.movimiento = r); // consulta al servicio
      });
  }

}

此方法订阅服务返回的Observable<Movement>。这是DatosServicegetMovimientoBy_Id$(_id)方法:

getMovimientoBy_Id$(_id): Observable<Movimiento> {
  return this.http
    .get(`priv/movimientos/${_id}`)
    .map(r => r.json());
}

我已经尝试过这段代码来测试组件:

describe('EditorComponent', () => {
  let movimiento = new Movimiento(new Date(), 0, 1, 1);
  let component: EditorComponent;
  let fixture: ComponentFixture<EditorComponent>;
  let datosService: DatosService;

  beforeEach(async(() => {
    let activatedRouteMock = {
      route: Observable.of({ id: 1 })
    }

    TestBed.configureTestingModule({
      imports: [
        HttpModule
      ],
      declarations: [
        EditorComponent
      ],
      providers: [
        DatosService,
        { provide: ActivatedRoute, useValue: activatedRouteMock }
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(EditorComponent);
    component = fixture.componentInstance;
    datosService = fixture.debugElement.injector.get(DatosService);
  });

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

  it('should create movimiento', (done) => {
    let spy = spyOn(datosService, 'getMovimientoBy_Id$').and.returnValue(Observable.of(movimiento));
    fixture.detectChanges();
    expect(component.movimiento).toBeTruthy();
    });
});

第一个测试通过,但在第二个我得到了这个异常

未捕获的错误:0:0 中的错误原因:无法读取未定义的属性“订阅”

我不明白我做错了什么......关于发生了什么的任何想法?谢谢。

【问题讨论】:

    标签: unit-testing angular jasmine observable


    【解决方案1】:

    Angular cli 停止在每个之前添加第二个。

     beforeEach(() => {
        fixture = TestBed.createComponent(EditorComponent);
        component = fixture.componentInstance;
        datosService = fixture.debugElement.injector.get(DatosService);
      });
    

    这是有道理的,因为您通常希望在开始测试之前模拟数据。

    但你的实际问题是你如何模拟路由器。您需要添加到 route 属性 params 否则 params 为空

    尝试以下操作:

    describe('EditorComponent', () => {
      let movimiento = new Movimiento(new Date(), 0, 1, 1);
    
    
    beforeEach(async(() => {
        let activatedRouteMock = {
          route: {
            params: {
              Observable.of({ id: 1 })
            }
          }
        }
    
        TestBed.configureTestingModule({
          imports: [
            HttpModule
          ],
          declarations: [
            EditorComponent
          ],
          providers: [
            DatosService,
            { provide: ActivatedRoute, useValue: activatedRouteMock }
          ]
        })
          .compileComponents();
      }));
    
      it('should create', () => {
        var component = fixture.componentInstance;
        expect(component).toBeTruthy();
      });
    
      it('should create movimiento', (done) => {
        var datosService = TestBed.get(DatosService);
        let spy = spyOn(datosService, 'getMovimientoBy_Id$').and.returnValue(Observable.of(movimiento));
    
        var fixture = TestBed.createComponent(EditorComponent);
        var component = fixture.componentInstance;
        fixture.detectChanges();
        expect(component.movimiento).toBeTruthy();
      });
    });
    

    【讨论】:

    • 嗨!我使用最新版本 angular-cli 创建了项目,它创建了两种方法(异步和同步一种)。无论如何,使用你的代码我得到了同样的异常。
    • 最后我解决了,问题是ActivatedRoute 没有路由属性,所以这样声明:let activatedRouteMock = { params: Observable.of({ id: 1 }) } 完美运行,这就是我得到undefined 的原因。
    • @EliasGarcia 但这与您的问题相同
    • 是的,我看到参数应该在根目录中;0
    • 是的,我没有注意到,这是你的答案和我的错误的合并;D
    猜你喜欢
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多