简体   繁体   English

在angular2中测试router-outlet组件

[英]testing router-outlet component in angular2

i have a homecomponent where the html is 我有一个html所在的homecomponent

//home.component.html //home.component.html

<router-outlet></router-outlet>

//home.component.ts //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 //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');
            }


        }));
});

I am getting the following error 我收到以下错误

    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)

what is the mistake i am doing ? 我在做什么错?

Thanks in advance 提前致谢

The error is because the <router-outlet> in part of the RouterModule 1 , which is not imported into your test bed configuration. 该错误是因为RouterModule 1中<router-outlet>未导入到您的测试台配置中。

If you don't care to test any actual real routing (I notice the mock router), then you can just make Angular ignore the <router-outlet> element by adding the following into your test bed configuration. 如果您不关心测试任何实际的实际路由(我注意到模拟路由器),那么您可以通过在测试台配置中添加以下内容来使Angular忽略<router-outlet>元素。

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

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

And just a suggestion. 只是一个建议。 You want to test the behavior on the component, and the behavior is that when the component is created and the user authenticated, then the router navigate method should be called. 您希望测试组件上的行为,并且行为是在创建组件并对用户进行身份验证时,应调用路由器导航方法。 So we should test that the navigate method is called. 所以我们应该测试一下调用导航方法。 How do we do that? 我们怎么做? With Spies . 间谍 You can make a spy from the navigateByUrl method, then you can check with jasmine if that method was called 您可以从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');
});

UPDATE UPDATE

Now you are getting a missing Http provider error. 现在你得到一个缺少的Http提供程序错误。

Because you have providers:[HomeService] on your @Component , it overrides the one in the test module configuration (which is the mock). 因为@Component上有providers:[HomeService] ,它会覆盖测试模块配置中的提供者(即模拟)。 You should override the component providers the in this case 在这种情况下,您应该覆盖组件提供程序

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

1 - For testing it should actually be the RouterTestingModule , as mentioned here 1 -为了测试它实际上应该是RouterTestingModule ,提到这里

If you don't want to test routing but want to test the functionality of the component, you can just add 如果您不想测试路由但想要测试组件的功能,则可以添加

  <!-- app.component.spec.ts --> import { RouterTestingModule } from '@angular/router/testing'; TestBed.configureTestingModule({ imports: [RouterTestingModule], declarations: [AppComponent], }); 

This allows your test to run without disabling CUSTOM_ELEMENTS_SCHEMA 这允许您的测试在不禁用CUSTOM_ELEMENTS_SCHEMA的情况下运行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM