typescript 如何测试Angular 7ngOnInIt这一点有保证吗?

j13ufse2  于 2022-11-26  发布在  TypeScript
关注(0)|答案(1)|浏览(89)

我想测试一个由我的ngoninit函数完成的简单赋值。
ngOnInIt函数基本上是这样做的:

async ngOnInit() {
     Promise.all([
      this.storage.get('current-data'),
      this.storage.get('uuid'),
    ]).then(async (values) => {
 
  const dataObject: any = values[0];
  const uuid = values[1];

  // get the data object for this data

  await this.dataService
    .getAllData()
    .then((data) => {
          this.data = data;
    });
 });

()}}
所以基本上
我想测试数据的长度,但一直收到以下错误:

ERROR: 'Unhandled Promise rejection:', 'Cannot read properties of undefined (reading 'length')', '; Zone:', 'ProxyZone', '; Task:', 'Promise.then', '; Value:', TypeError: Cannot read properties of undefined (reading 'length')
TypeError: Cannot read properties of undefined (reading 'length')
    at apply (http://localhost:9876/_karma_webpack_/webpack:/src/app/pages/survey/survey.page.spec.ts:128:32)
    at _ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:409:30)
    at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:303:43)
    at _ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:408:56)
    at Zone.run (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:169:47)
    at apply (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:1326:38)
    at _ZoneDelegate.invokeTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:443:35)
    at ProxyZoneSpec.onInvokeTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:334:43)
    at _ZoneDelegate.invokeTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:442:64)
    at Zone.runTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:214:51), 'TypeError: Cannot read properties of undefined (reading 'length')
    at apply (http://localhost:9876/_karma_webpack_/webpack:/src/app/pages/survey/survey.page.spec.ts:128:32)
    at _ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:409:30)
    at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:303:43)
    at _ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:408:56)
    at Zone.run (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:169:47)
    at apply (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:1326:38)
    at _ZoneDelegate.invokeTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:443:35)
    at ProxyZoneSpec.onInvokeTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:334:43)
    at _ZoneDelegate.invokeTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:442:64)

在我的spec.ts文件中,这里是我为测试它而编写的代码。

describe('initialzation', async () => {
        beforeEach(async () => {
          const dataService =
            fixture.debugElement.injector.get(DataService);
          const spy = spyOn(dataService, 'getAllData').and.returnValue(
            Promise.resolve(stubValueData)
          );
          (StorageServiceSpy.get as any)
            .withArgs({ key: 'current-data' })
            .and.returnValue(Promise.resolve(JSON.stringify(stubValueCurrentData)));
          (StorageServiceSpy.get as any)
            .withArgs({ key: 'uuid' })
            .and.returnValue(Promise.resolve(uniqueId));
          (StorageServiceSpy.get as any)
            .withArgs({ key: 'data' })
            .and.returnValue(Promise.resolve(JSON.stringify(stubValueData)));
    
          fixture.detectChanges();
        });
    
        it('should verify that the arguments are all set', async () => {
          fixture.whenStable().then(() => {
            // wait for async getData
            fixture.detectChanges(); // update view with Tasks
            expect(component.data.length).toEqual(stubValueData.length);
            
          });
        });
      });

测试床配置测试模块为:

beforeEach(async () => {
    routeStub = {
      snapshot: {
        paramMap: convertToParamMap({
          data_id: String(stubValueDatas[0].data_id),
        }),
      },
    };

    const spyStorage = jasmine.createSpyObj('Storage', [
      'create',
      'get',
      'set',
    ]);
    TestBed.configureTestingModule({
      declarations: [SurveyPage],
      imports: [IonicModule.forRoot(), RouterTestingModule],
      providers: [
        {
          provide: Storage,
          useValue: spyStorage,
        },
        { provide: ActivatedRoute, useValue: routeStub },
        {
          provide: NavController,
          useClass: NavMock,
        },
        HttpClient,
        HttpHandler,
      ],
    }).compileComponents();

    fixture = TestBed.createComponent(SurveyPage);
    StorageServiceSpy = TestBed.inject(Storage) as jasmine.SpyObj<Storage>;
    navControllerSpy = TestBed.inject(
      NavController
    ) as jasmine.SpyObj<NavController>;
    component = fixture.componentInstance;
    fixture.detectChanges();
    await fixture.whenStable();
  });

你能帮我修正这个错误吗?我不明白为什么我得到了未定义的长度。它应该可以工作。我不想在spec.ts文件中捕获这个错误,因为如果我这样做的话,其他except函数在得到错误时将无法工作。

xzv2uavs

xzv2uavs1#

在第一个beforeEach(TestBed.configureTestingModule)中删除这些行。

fixture.detectChanges();
    await fixture.whenStable();

然后把它们加到第二个beforeEach上。

beforeEach(async () => {
          const dataService =
            fixture.debugElement.injector.get(DataService);
          const spy = spyOn(dataService, 'getAllData').and.returnValue(
            Promise.resolve(stubValueData)
          );
          (StorageServiceSpy.get as any)
            .withArgs({ key: 'current-data' })
            .and.returnValue(Promise.resolve(JSON.stringify(stubValueCurrentData)));
          (StorageServiceSpy.get as any)
            .withArgs({ key: 'uuid' })
            .and.returnValue(Promise.resolve(uniqueId));
          (StorageServiceSpy.get as any)
            .withArgs({ key: 'data' })
            .and.returnValue(Promise.resolve(JSON.stringify(stubValueData)));
    
          fixture.detectChanges();
          await fixture.whenStable();
        });

这个问题出现在第一个beforeEach中,我们调用fixture.detectChanges(),这会导致ngOnInit运行,但我们还没有模拟ngOnInit的依赖关系,因此它抱怨这些不是承诺。
此外,请删除此处的async,它不会执行任何操作:

describe('initialzation', async () => {

相关问题