Angular 4单元测试-无法读取未定义的属性"root" [英] Angular 4 unit test - Cannot read property 'root' of undefined

查看:54
本文介绍了Angular 4单元测试-无法读取未定义的属性"root"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的单元测试有问题.我不知道这个测试有什么问题.我搜索了一个令人沮丧的东西,但对我来说没有任何用处.当我要模拟路由器时,出现错误TypeError: Cannot read property 'root' of undefined. 感谢advace的帮助.

I've got a problem with my unit test. I don't know what's wrong with this test. I've searched a soulations but nothing works for me. When I want to mock Router I have an error TypeError: Cannot read property 'root' of undefined. Thanks in advace for any help.

错误:

 TypeError: Cannot read property 'root' of undefined
        at rootRoute (webpack:///~/@angular/router/@angular/router.es5.js:5880:0 <- src/test.ts:53760:30)
        at DynamicTestModuleInjector.get (ng:///DynamicTestModule/module.ngfactory.js:401:75)
        at DynamicTestModuleInjector.getInternal (ng:///DynamicTestModule/module.ngfactory.js:919:55)
        at DynamicTestModuleInjector.NgModuleInjector.get (webpack:///~/@angular/core/@angular/core.es5.js:3556:25 <- src/test.ts:3909:44)
        at resolveDep (webpack:///~/@angular/core/@angular/core.es5.js:11017:0 <- src/test.ts:11370:45)
        at createClass (webpack:///~/@angular/core/@angular/core.es5.js:10881:0 <- src/test.ts:11234:32)
        at createDirectiveInstance (webpack:///~/@angular/core/@angular/core.es5.js:10701:21 <- src/test.ts:11054:37)
        at createViewNodes (webpack:///~/@angular/core/@angular/core.es5.js:12064:33 <- src/test.ts:12417:49)
        at createRootView (webpack:///~/@angular/core/@angular/core.es5.js:11969:0 <- src/test.ts:12322:5)
        at callWithDebugContext (webpack:///~/@angular/core/@angular/core.es5.js:13184:25 <- src/test.ts:13537:42)
        at Object.debugCreateRootView [as createRootView] (webpack:///~/@angular/core/@angular/core.es5.js:12644:0 <- src/test.ts:12997:12)
        at ComponentFactory_.create (webpack:///~/@angular/core/@angular/core.es5.js:9890:25 <- src/test.ts:10243:46)
        at initComponent (webpack:///~/@angular/core/@angular/core/testing.es5.js:800:0 <- src/test.ts:55130:49)
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:365:0 <- src/test.ts:151874:26)
        at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- src/test.ts:118466:39)
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:364:0 <- src/test.ts:151873:32)
    TypeError: Cannot read property 'form' of undefined
        at updateForm (webpack:///src/app/auth/login/login.component.spec.ts:62:14 <- src/test.ts:64296:18)
        at Object.<anonymous> (webpack:///src/app/auth/login/login.component.spec.ts:88:4 <- src/test.ts:64316:9)
        at Object.<anonymous> (webpack:///~/@angular/core/@angular/core/testing.es5.js:336:0 <- src/test.ts:54666:26)
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:365:0 <- src/test.ts:151874:26)
        at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- src/test.ts:118466:39)
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:364:0 <- src/test.ts:151873:32)
        at Zone.run (webpack:///~/zone.js/dist/zone.js:125:0 <- src/test.ts:151634:43)
        at Object.<anonymous> (webpack:///~/zone.js/dist/jasmine-patch.js:104:0 <- src/test.ts:118180:34)
        at webpack:///~/@angular/core/@angular/core/testing.es5.js:96:0 <- src/test.ts:54426:17
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:365:0 <- src/test.ts:151874:26)
        at AsyncTestZoneSpec.onInvoke (webpack:///~/zone.js/dist/async-test.js:49:0 <- src/test.ts:117775:39)

测试方法:

onSubmit(): void {
const payload = this.form.value;
this.form.reset();
this.form.disable();

this.authService.login(payload)
  .finally(() => {
    this.form.enable();
  })
  .subscribe(
    ({ res }) => {
      if (typeof res.cmp === 'undefined' || typeof res.rel === 'undefined') {
        this.router.navigate(['test']);
      } else {
        this.router.navigate([this.returnUrl]);
      }
    },
    ({ sts }) => {
      this.dialogService.alert({
        title: 'Error',
        message: `${backendMessage(sts, false)}`
      });
    }
  );

}

单元测试:

const mockUser = {
  email: 'test@test.test',
  password: 'Test1235',
  remember: true
};

const mockInvalidUser = {
  email: null,
  password: null,
  remember: true
};

@Injectable()
class AuthServiceMock {

  login(payload: any): Observable<BackendResponse<Auth>> {
    let sessionObj: BackendResponse<Auth> = { sts: null, res: { cmp: null, rel: null, prs: null } };
    return Observable.of(sessionObj);
  }
}

const router = {
  navigate: jasmine.createSpy('navigate')
};

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [AuthModule, AppModule],
      providers: [
        ExtendedFormBuilder,
        { provide: AuthService, useClass: AuthServiceMock },
        { provide: Router, useValue: router }
      ],
    }).compileComponents();
  }));

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

  function updateForm(userEmail: string, userPassword: string): void {
    component.form.controls['prs.email'].setValue(userEmail);
    component.form.controls['prs.passwd'].setValue(userPassword);
  }

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

  it('return url should have a default value', () => {
    expect(component.returnUrl).toBeTruthy();
  });

  it('check form controls values after update', fakeAsync(() => {
    updateForm(mockUser.email, mockUser.password);
    expect(component.form.controls['prs.email'].value).toEqual(mockUser.email);
    expect(component.form.controls['prs.passwd'].value).toEqual(mockUser.password);
  }));

  it('check if the form is valid after set incorrect values', fakeAsync(() => {
    updateForm(mockInvalidUser.email, mockInvalidUser.password);
    expect(component.form.valid).toBeFalsy();
  }));

  fit('should update model on submit', fakeAsync(() => {
    updateForm(mockUser.email, mockUser.password);
    component.onSubmit();
    expect(router.navigate).toHaveBeenCalledWith(['./']);
  }));
});

推荐答案

我可能会误会,但是看起来您并没有对实际模板本身做任何事情.因此,执行此操作的最简单方法是仅从"@ angular/core"导入NO_ERROR_SCHEMA,并在您的测试平台配置中将其提供为

I could be mistaken, but it doesn't look like you're doing anything with the actual template itself. So the easiest way to get this going would be to just import the NO_ERROR_SCHEMA from '@angular/core', and provide it in your testbed configuration as

providers: [...],
schemas: [NO_ERROR_SCHEMA]

现在,如果/当您到达要测试模板的地步时,那么您还有更多选择.您可以提供一些路由器存根,如测试项目.它们在测试文件夹下.使用这些并将它们放在测试平台声明中,至少应该可以解决路由问题.您也可以只创建自己的存根.或者,您可以配置RouterTestingModule.withRoutes([]).

Now if/when you get to a point that you also want to test the template, then you have a few more options. You can provide some router stubs, as shown in the angular test project. They're under the testing folder. Use those and put them in the testbed declarations, and that should resolve at least the routing issue. You could also just create your own stubs. Or, you could configure the RouterTestingModule.withRoutes([]).

希望这会有所帮助.

这篇关于Angular 4单元测试-无法读取未定义的属性"root"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆