【问题标题】:testing router-outlet component in angular2在angular2中测试路由器插座组件
【发布时间】:2016-09-30 13:30:39
【问题描述】:

我有一个 html 所在的 homecomponent

//home.component.html

<router-outlet></router-outlet>

//home.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { HomeService} from './shared/services/home.service';

@Component({
  // moduleId: module.id,
  selector: 'app-home',
  templateUrl: 'home.component.html',
  styleUrls: ['home.component.css'],
  providers:[HomeService]
})
export class HomeComponent implements OnInit {

  constructor(private service:HomeService , private route:Router) { }

  ngOnInit() {
    if(this.service.isAuthenticated()){
      this.route.navigateByUrl('dashboard/main');
    }
  }
}

//home.component.spec.ts

import { ComponentFixture, TestBed  } from '@angular/core/testing';
import { By }              from '@angular/platform-browser';
import { DebugElement }    from '@angular/core';
import { async, inject } from '@angular/core/testing';
import { HomeComponent } from './home.component';
import { Router} from '@angular/router';
import { HomeService } from './shared/services/home.service';

class RouterStub {
    navigateByUrl(url: string) { return url }
}

class MockHomeService {
    isAuthenticated() {
        return true
    }
}

let comp: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;


describe('Component: HomeComponent', () => {


    beforeEach(() => {
        TestBed.configureTestingModule({

            declarations: [HomeComponent],
            providers: [
                { provide: Router, useClass: RouterStub },
                { provide: HomeService, useClass: MockHomeService },
            ]
        });

        fixture = TestBed.createComponent(HomeComponent);
        comp = fixture.componentInstance;

    });

    it('should tell ROUTER to navigate to dashboard/main if authencated',
        inject([Router, HomeService], (router: Router, homeservice: HomeService) => {
            const spy = spyOn(router, 'navigateByUrl');
            comp.ngOnInit();
            if (homeservice.isAuthenticated()) {
                const navArgs = spy.calls.first().args[0];
                expect(navArgs).toBe('dashboard/main');
            }


        }));
});

我收到以下错误

    Error: Template parse errors:
        'router-outlet' is not a known element:
        1. If 'router-outlet' is an Angular component, then verify that it is pa
rt of this module.
        2. If 'router-outlet' is a Web Component then add "CUSTOM_ELEMENTS_SCHEM
A" to the '@NgModule.schema' of this component to suppress this message. ("<div
class="">
            [ERROR ->]<router-outlet></router-outlet>
        </div>
        "): HomeComponent@1:4
            at TemplateParser.parse (http://localhost:9876/_karma_webpack_/0.bun
dle.js:21444:19)
            at RuntimeCompiler._compileTemplate (http://localhost:9876/_karma_we
bpack_/0.bundle.js:6569:51)
            at http://localhost:9876/_karma_webpack_/0.bundle.js:6492:83
            at Set.forEach (native)
            at compile (http://localhost:9876/_karma_webpack_/0.bundle.js:6492:4
7)
            at RuntimeCompiler._compileComponents (http://localhost:9876/_karma_
webpack_/0.bundle.js:6494:13)
            at RuntimeCompiler._compileModuleAndAllComponents (http://localhost:
9876/_karma_webpack_/0.bundle.js:6411:37)
            at RuntimeCompiler.compileModuleAndAllComponentsSync (http://localho
st:9876/_karma_webpack_/0.bundle.js:6399:21)
            at TestingCompilerImpl.compileModuleAndAllComponentsSync (http://loc
alhost:9876/_karma_webpack_/0.bundle.js:10203:35)
            at TestBed._initIfNeeded (webpack:///D:/myapp/transfer(9)/transfer/~
/@angular/core/bundles/core-testing.umd.js:1059:0 <- src/test.ts:4943:40)

我做错了什么?

提前致谢

【问题讨论】:

  • 请使用 routing 代码和 appComponent 代码更新您的答案。这将有助于识别问题。

标签: angular angular2-routing angular2-testing


【解决方案1】:

错误是因为&lt;router-outlet&gt;RouterModule1 的一部分,它没有导入到您的测试台配置中。

如果您不想测试任何实际的真实路由(我注意到模拟路由器),那么您可以通过将以下内容添加到测试台配置中来让 Angular 忽略 &lt;router-outlet&gt; 元素。

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

TestBed.configureTestingModule({
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
});

只是一个建议。你想测试组件的行为,行为是当组件被创建并且用户被认证时,应该调用路由导航方法。所以我们应该测试是否调用了 navigate 方法。我们如何做到这一点?与Spies。您可以从navigateByUrl 方法中创建一个间谍,然后您可以使用 jasmine 检查该方法是否被调用

import { getTestBed } from '@angular/core/testing';

class RouterStub {
  navigateByUrl = jasmine.createSpy('navigateByUrl');
}

it('should navigate', () => {
  fixture.detectChanges();
  let router: Router = getTestBed().get(Router);
  expect(router.navigateByUrl).toHaveBeenCalledWith('dashboard/main');
});

更新

现在您收到了缺少的Http 提供程序错误。

因为您的@Component 上有providers:[HomeService],它会覆盖测试模块配置中的那个(即模拟)。在这种情况下,您应该覆盖组件提供程序

TestBed.configureTestingModule({});
TestBed.overrideComponent(HomeComponent, {
  set: {
    providers: [
      { provide: HomeService, useClass: MockHomeService }
    ]
  }
})

1 - 对于测试,它实际上应该是RouterTestingModule,正如提到的here

【讨论】:

  • 谢谢,我导入了 CUSTOM_ELEMENTS_SCHEMA 并在测试台配置中包含了架构:[ CUSTOM_ELEMENTS_SCHEMA ],但收到以下错误 te:0:0 caused by: No provider for Http! Error: No provider for Http! at NoProviderError.Error (native) at NoProviderError.BaseError [as constructor] (webpack:///D:/myfolder/t ransfer(9)/transfer/~/@angular/core/src/facade/errors.js:24:0 &lt;- src/test.ts: 2:34) at NoProviderError .AbstractProviderError [as constructor] (webpack:///D:/myfolder/transfer(9)/transfer/~/@angular/core/src/di/reflective_errors.js:42:0 &lt;- src/test.ts:28434:16)
【解决方案2】:

如果你不想测试路由但想测试组件的功能,你可以添加

  <!-- app.component.spec.ts -->
  import { RouterTestingModule } from '@angular/router/testing';

  TestBed.configureTestingModule({
    imports: [RouterTestingModule],
    declarations: [AppComponent],
  });

这允许您在不禁用 CUSTOM_ELEMENTS_SCHEMA 的情况下运行测试

【讨论】:

    猜你喜欢
    • 2016-04-23
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 2017-03-21
    • 2016-09-05
    • 2016-11-18
    • 2017-06-02
    相关资源
    最近更新 更多