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

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

问题描述

我的单元测试有问题.我不知道这个测试有什么问题.我已经搜索了一个灵魂,但没有什么对我有用.当我想模拟路由器时,我有一个错误 TypeError: Cannot read property 'root' of undefined.在此先感谢您的帮助.

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]

现在,如果/当您还想测试模板时,那么您还有更多选择.您可以提供一些路由器存根,如 angular 所示测试项目.它们在测试文件夹下.使用这些并将它们放在测试台声明中,这至少应该解决路由问题.您也可以创建自己的存根.或者,您可以配置 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天全站免登陆