在Angular9单元测试中订阅激活的路由参数

时间:2020-04-05 23:14:13

标签: karma-jasmine angular9

我遇到了一个测试以下Angular 9组件的问题单元:

export class BirdsDetailComponent implements OnInit {
  ...

  constructor(private service: BirdsService
    , private flickr: FlickrService
    , private route: ActivatedRoute
    , private location: Location
    , private router: Router) {
    route.params.subscribe(_ => {
      this.route.paramMap.subscribe(pmap => this.getData(+pmap.get('id')));
    });
  }

  ngOnInit() {}

  getData(id: number): void { ... }

与我熟悉的其他组件不同,该组件可从构造函数中启动数据检索。

我在设置route参数时遇到了问题(我认为)。我尝试了多种设置激活的路由模拟/存根的方法。包括在Angular docs的此设置中找到的那个。

describe('BirdsDetailComponent', () => {

  let component: BirdsDetailComponent;
  let fixture: ComponentFixture<BirdsDetailComponent>;

  let activatedRoute: ActivatedRouteStub;

  beforeEach(() => {
    activatedRoute = new ActivatedRouteStub();
  });

  let mockBirdsService;
  let mockFlickrService;

  // the `id` value is irrelevant because ignored by service stub
  beforeEach(() => activatedRoute.setParamMap({ id: 99999 }));

  beforeEach(async(() => {
    const routerSpy = createRouterSpy();
    function createRouterSpy() {
      return jasmine.createSpyObj('Router', ['navigate']);
    }
    mockBirdsService = jasmine.createSpyObj(['getData']);

    TestBed.configureTestingModule({
      imports: [RouterTestingModule.withRoutes([])],
      declarations: [BirdsDetailComponent],
      providers: [
        { provide: BirdsService, useValue: mockBirdsService },
        { provide: FlickrService, useValue: mockFlickrService },
        { provide: Router, useValue: routerSpy },
        {
          provide: ActivatedRoute, useValue: ActivatedRouteStub
        }
        // {
        //   provide: ActivatedRoute,
        //   useValue: {
        //     params: of({ id: '123' })
        //   }
        // }
      ]
    })
      .compileComponents();
  }));


  beforeEach(() => {
    fixture = TestBed.createComponent(BirdsDetailComponent);
    component = fixture.componentInstance;

    activatedRoute.setParamMap({ id: 1 });
  });

  it('should call getData', () => {
    const conserveStatus = {
      conservationStatusId: 1, conservationList: 'string',
      conservationListColourCode: 'string', description: 'string', creationDate: 'Date | string',
      lastUpdateDate: 'Date | string', birds: []
    };

    const bird = {
      birdId: 1, class: 'string', order: 'string', family: 'string',
      genus: 'string', species: 'string', englishName: 'string', populationSize: 'string',
      btoStatusInBritain: 'string', thumbnailUrl: 'string', songUrl: 'string',
      birderStatus: 'string', birdConservationStatus: conserveStatus,
      internationalName: 'string', category: 'string', creationDate: 'Date | string',
      lastUpdateDate: 'Date | string'
    };

    mockBirdsService.getData.and.returnValue(of(bird));

    fixture.detectChanges();
    // // Act or change
    // component.getBird(1);

    // // fixture.detectChanges();

    // Assert
    expect(mockBirdsService.getBird).toHaveBeenCalled();
  });

});

我还尝试了激活路由参数的简单设置,您可以在注释掉的代码中看到这样的代码(及其变化形式):

 {
   provide: ActivatedRoute,
   useValue: {
     params: of({ id: '123' })
   }
 }

无论我尝试什么,我似乎也遇到了“无法读取未定义抛出的属性”订阅”错误。问题可能与检测更改有关吗?谁能指出我正确的方向?

0 个答案:

没有答案