Javascript 单元测试时,无法解析 Angular RC 5 中路由器的所有参数:(?, ?, ?, ?, ?, ?, ?)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39015918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:07:46  来源:igfitidea点击:

Can't resolve all parameters for Router: (?, ?, ?, ?, ?, ?, ?) in Angular RC 5 when unit testing

javascriptunit-testingangulartypescriptangular2-routing

提问by ganjan

I just upgraded to Angular RC 5 and now all component that uses 'ROUTER_DIRECTIVES' fails with 'Can't resolve all parameters for Router: (?, ?, ?, ?, ?, ?, ?)' when I try to unit test the component.

我刚刚升级到 Angular RC 5,现在所有使用“ROUTER_DIRECTIVES”的组件都失败了,并在我尝试单元测试时显示“无法解析路由器的所有参数:(?, ?, ?, ?, ?, ?, ?)”组件。

import { inject, addProviders } from '@angular/core/testing';
import { ComponentFixture, TestComponentBuilder } from '@angular/core/testing';
import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES, Router } from '@angular/router';

import { HomeComponent } from './home.component';
import { UserService } from '../_services/user.service';

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

  beforeEach(() => {
    addProviders([HomeComponent, UserService, ROUTER_DIRECTIVES, Router]);
  });  

  it('should inject the component', inject([HomeComponent, UserService, ROUTER_DIRECTIVES, Router],
    (component: HomeComponent) => {
      expect(component).toBeTruthy();
      // expect(component.currentUser.firstname).toEqual('Jan');
    }));

The full error log:

完整的错误日志:

     Chrome 52.0.2743 (Windows 10 0.0.0)
   Error: Can't resolve all parameters for Router: (?, ?, ?, ?, ?, ?, ?).
       at new BaseException (webpack:///C:/ng/anbud/~/@angular/compiler/src/facade/exceptions.js:27:0 <- src/test.ts:2943:23)
       at CompileMetadataResolver.getDependenciesMetadata (webpack:///C:/ng/anbud/~/@angular/compiler/src/metadata_resolver.js:551:0 <- src/test.ts:24542:19)
       at CompileMetadataResolver.getTypeMetadata (webpack:///C:/ng/anbud/~/@angular/compiler/src/metadata_resolver.js:448:0 <- src/test.ts:24439:26)
       at webpack:///C:/ng/anbud/~/@angular/compiler/src/metadata_resolver.js:594:0 <- src/test.ts:24585:41
       at Array.forEach (native)
       at CompileMetadataResolver.getProvidersMetadata (webpack:///C:/ng/anbud/~/@angular/compiler/src/metadata_resolver.js:575:0 <- src/test.ts:24566:19)
       at CompileMetadataResolver.getNgModuleMetadata (webpack:///C:/ng/anbud/~/@angular/compiler/src/metadata_resolver.js:305:0 <- src/test.ts:24296:58)
       at RuntimeCompiler._compileComponents (webpack:///C:/ng/anbud/~/@angular/compiler/src/runtime_compiler.js:150:0 <- src/test.ts:37986:47)
       at RuntimeCompiler._compileModuleAndAllComponents (webpack:///C:/ng/anbud/~/@angular/compiler/src/runtime_compiler.js:78:0 <- src/test.ts:37914:37)
       at RuntimeCompiler.compileModuleAndAllComponentsSync (webpack:///C:/ng/anbud/~/@angular/compiler/src/runtime_compiler.js:52:0 <- src/test.ts:37888:21)

Any ideas how to unit test components with routing?

任何想法如何使用路由对组件进行单元测试?

采纳答案by ganjan

Was finally able to fix it, and it was as simple as this:

终于能够修复它,就这么简单:

beforeEach(() => addProviders([
    { 
        provide: Router, 
        useClass: class { navigate = jasmine.createSpy("navigate"); }
    }]));

回答by Jules

for me it worked to add the RouterTestingModule

对我来说,添加 RouterTestingModule 是有效的

  import { RouterTestingModule } from '@angular/router/testing';

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [ HomeComponent ]
    })
    .compileComponents();
  }));

回答by masterwok

I did not have any luck with the above solutions. Instead, I followed the recommended approach in the official documentation: Testing Routed Components

我对上述解决方案没有任何运气。相反,我遵循了官方文档中推荐的方法:Testing Routed Components

First, create a stubbed router with whatever methods your component calls:

首先,使用您的组件调用的任何方法创建一个存根路由器:

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

Then, when configuring your testing module you do the following:

然后,在配置测试模块时,您执行以下操作:

TestBed.configureTestingModule({
  declarations: [HeaderComponent],
  providers: [
    {provide: Router, useClass: RouterStub}
  ]
});

回答by Koji D'infinte

In my case, I had Router in providers and RouterTestingModule in imports. Guess this was causing a conflict. The following configuration worked:

就我而言,我在提供者中有路由器,在导入中有 RouterTestingModule。估计这引起了冲突。以下配置有效:

    TestBed.configureTestingModule({
        declarations: [Component],
        imports: [
            RouterTestingModule,             
        ],
        providers: [
         ...         //Remove Router from providers
        ]              

    });

回答by ByTheWayer

Try adding RouterModule:

尝试添加 RouterModule:

import { ROUTER_DIRECTIVES, Router, RouterModule } from '@angular/router';

beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                 ...
                {provide: Router, useClass: RouterModule},
        });
    });

回答by Felipe Bejarano

I just had to remove the router from the providers. That was causing the problem for me.

我只需要从提供商那里删除路由器。这给我造成了问题。

回答by Siddhartha Thota

I was getting the same error, importing RouterTestModule in my imports array, and removing Router/ActivatedRoute from providers and also removing RouterModule from my imports array helped me to get over this issue.

我遇到了同样的错误,在我的导入数组中导入 RouterTestModule,从提供者中删除 Router/ActivatedRoute 并从我的导入数组中删除 RouterModule 帮助我解决了这个问题。

This is how my working version looks like

这是我的工作版本的样子

import { RouterTestingModule } from '@angular/router/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { MyAppComponent } from './my-apppp.component';
import { MyAppService } from '../../../services/my-app.service';
import { NO_ERRORS_SCHEMA} from '@angular/core';

 beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ MyAppComponent ],
      schemas:      [NO_ERRORS_SCHEMA],
      imports: [ FormsModule, RouterTestingModule ],
      providers: [ MyAppService ]
    })
    .compileComponents();
  }));

I know a lot of people already commented in here, but I felt like providing a updated answer would be helpful.

我知道很多人已经在这里发表了评论,但我觉得提供更新的答案会有所帮助。

Thanks!

谢谢!

回答by Rash

For latest Angular 7, here is the solution that worked for me. The example is copied from latest angular docs.

对于最新的 Angular 7,这是对我有用的解决方案。该示例是从最新的角度文档中复制的。

app/dashboard/dashboard.component.spec.ts (spies)

app/dashboard/dashboard.component.spec.ts(间谍)

const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
const heroServiceSpy = jasmine.createSpyObj('HeroService', ['getHeroes']);

TestBed.configureTestingModule({
  providers: [
    { provide: HeroService, useValue: heroServiceSpy },
    { provide: Router,      useValue: routerSpy }
  ]
})

app/dashboard/dashboard.component.spec.ts (navigate test)

app/dashboard/dashboard.component.spec.ts(导航测试)

it('should tell ROUTER to navigate when hero clicked', () => {

  heroClick(); // trigger click on first inner <div class="hero">

  // args passed to router.navigateByUrl() spy
  const spy = router.navigateByUrl as jasmine.Spy;
  const navArgs = spy.calls.first().args[0];

  // expecting to navigate to id of the component's first hero
  const id = comp.heroes[0].id;
  expect(navArgs).toBe('/heroes/' + id,
    'should nav to HeroDetail for first hero');
});