Angular 角度单元测试.使用存根模拟子组件

Angular 角度单元测试.使用存根模拟子组件,angular,typescript,unit-testing,jasmine,Angular,Typescript,Unit Testing,Jasmine,我试图对一个组件进行单元测试,该组件有一个子组件,我想模拟它。我不想使用NO_ERRORS_模式,因为它会带来相关的缺点。我正在尝试使用存根/虚拟子组件。代码如下: parent.component.ts @Component({ selector: 'parent', template: ` <!-- Does other things --> <child></child> ` }) export class ParentCom

我试图对一个组件进行单元测试,该组件有一个子组件,我想模拟它。我不想使用NO_ERRORS_模式,因为它会带来相关的缺点。我正在尝试使用存根/虚拟子组件。代码如下:

parent.component.ts

@Component({
  selector: 'parent',
  template: `
    <!-- Does other things -->
    <child></child>
  `
})
export class ParentComponent { }
@Component({
  selector: 'child',
  template: '<!-- Does something -->'
})
export class ChildComponent {
  @Input() input1: string;
  @Input() input2?: number;
}
describe('ParentComponent', () => {
  let component: ParentComponent;
  let fixture: ComponentFixture<ParentComponent>;
  let router: Router;

  @Component({
    selector: 'child',
    template: '<div></div>'
  })
  class ChildStubComponent {
    @Input() input1: string;
    @Input() input2: number;
  }

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ParentComponent, ChildStubComponent ],
      imports: [
        AppRoutingModule, HttpClientModule, BrowserAnimationsModule,
        RouterTestingModule.withRoutes(routes)
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ParentComponent);
    component = fixture.componentInstance;
    router = TestBed.get(Router);
    spyOnProperty(router, 'url', 'get').and.returnValue('/somePath');
    fixture.detectChanges();
  });

  it('should create', () => {
    component.ngOnInit();
    expect(component).toBeTruthy();
  });
});
如果有帮助的话,我使用的是Angular版本8。到目前为止,我所看到的每一处都显示,您以与我现在相同的方式对子组件进行存根。使用ngmock目前还不是一个选项

编辑 尝试使用ngMock,但只有相同的问题。任何帮助都将不胜感激

解决方案


让它工作起来。问题是AppRoutingModule已经导入了真正的组件。

对于嵌套组件,我们可以这样模拟它们:

总之,您的父.component.spec.ts应该是:

import { HttpClientTestingModule} from '@angular/common/http/testing';
import { Component } from '@angular/core';

describe('ParentComponent', () => {
  let component: ParentComponent;
  let fixture: ComponentFixture<ParentComponent>;
  let router: Router;


 @Component({selector: 'child', template: ''})
 class ChildStubComponent {}

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ParentComponent, ChildStubComponent ],
      imports: [
        AppRoutingModule, HttpClientTestingModule, BrowserAnimationsModule,
        RouterTestingModule.withRoutes(routes)
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ParentComponent);
    component = fixture.componentInstance;
    router = TestBed.get(Router);
    spyOnProperty(router, 'url', 'get').and.returnValue('/somePath');
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
从'@angular/common/http/testing'导入{HttpClientTestingModule};
从'@angular/core'导入{Component};
描述('ParentComponent',()=>{
let组件:ParentComponent;
let夹具:组件夹具;
让路由器:路由器;
@组件({选择器:'child',模板:'})
类ChildStubComponent{}
beforeach(异步(()=>{
TestBed.configureTestingModule({
声明:[ParentComponent,ChildStubComponent],
进口:[
ApprovitionModule、HttpClientTestingModule、BrowserAnimationsModule、,
RouterTestingModule.withRoutes(路由)
],
模式:[自定义元素\u模式]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(ParentComponent);
组件=fixture.componentInstance;
路由器=测试台.get(路由器);
spyOnProperty(路由器,'url','get')。和.returnValue('/somePath');
fixture.detectChanges();
});
它('应该创建',()=>{
expect(component.toBeTruthy();
});
});

您可能已经在AppRoutingModule中声明了(真实的)子组件。是否可以在没有该组件的情况下导入模块以进行测试?您可能可以使用。但是我首先要避免导入这个模块。导入/声明您在测试模块中需要的内容。太棒了!我让它工作了。非常感谢。
import { HttpClientTestingModule} from '@angular/common/http/testing';
import { Component } from '@angular/core';

describe('ParentComponent', () => {
  let component: ParentComponent;
  let fixture: ComponentFixture<ParentComponent>;
  let router: Router;


 @Component({selector: 'child', template: ''})
 class ChildStubComponent {}

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ParentComponent, ChildStubComponent ],
      imports: [
        AppRoutingModule, HttpClientTestingModule, BrowserAnimationsModule,
        RouterTestingModule.withRoutes(routes)
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ParentComponent);
    component = fixture.componentInstance;
    router = TestBed.get(Router);
    spyOnProperty(router, 'url', 'get').and.returnValue('/somePath');
    fixture.detectChanges();
  });

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