angular 单元测试 - 没有父组件的提供者
angular unit test - no provider for parent component
我正在创建自己的 angular bootstrap library,目前我一直在为导航栏编写单元测试。
我提炼了 the troubled unit test down to the bare essentials 以下是摘要:
单元测试
describe('BsNavbarDropdownComponent', () => {
let component: BsNavbarDropdownTestComponent;
let fixture: ComponentFixture<BsNavbarDropdownTestComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([])
],
declarations: [
// Component to test
BsNavbarDropdownComponent,
// Mock components
BsNavbarItemMockComponent,
// Testbench
BsNavbarDropdownTestComponent
],
providers: [
{ provide: BsNavbarItemComponent, useClass: BsNavbarItemMockComponent }
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(BsNavbarDropdownTestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@Component({
selector: 'bs-navbar-test',
template: `
<bs-navbar-item>
<a [routerLink]='[]'>dropdown</a>
<bs-navbar-dropdown>
<bs-navbar-item>
<a [routerLink]='["/b", "c"]'>bc</a>
</bs-navbar-item>
</bs-navbar-dropdown>
</bs-navbar-item>`
})
class BsNavbarDropdownTestComponent {
}
@Component({
selector: 'bs-navbar-item',
template: `
<li>
<ng-content></ng-content>
</li>`
})
class BsNavbarItemMockComponent {
}
待测单元
@Component({
selector: 'bs-navbar-dropdown',
templateUrl: './navbar-dropdown.component.html',
styleUrls: ['./navbar-dropdown.component.scss']
})
export class BsNavbarDropdownComponent {
constructor(
@Host() @Inject(forwardRef(() => BsNavbarItemComponent)) navbarItem: BsNavbarItemComponent
) {
this.navbarItem = navbarItem;
}
navbarItem: BsNavbarItemComponent;
}
在 BsNavbarDropdownTestComponent
中,显然 bs-navbar-dropdown
(BsNavbarDropdownComponent
) 有一个父标签 bs-navbar-item
(BsNavbarItemMockComponent
)。在要测试的单元中,我正在注入 BsNavbarItemComponent
,它在作为 BsNavbarItemMockComponent
.
提供的测试模块中
不过单元测试好像还是没有成功。
npm run nx run-many -- --target=test --projects=ng-bootstrap-demo --with-deps --watch=false --browsers=ChromeHeadless
结果:
FAIL xxx-ng-bootstrap libs/xxx-ng-bootstrap/src/lib/components/navbar/navbar-dropdown/navbar-dropdown.component.spec.ts
● BsNavbarDropdownComponent › should create
NG0201: No provider for BsNavbarItemComponent found in NodeInjector. Find more at https://angular.io/errors/NG0201
同样,请注意该模块具有以下供应商:
providers: [
{ provide: BsNavbarItemComponent, useClass: BsNavbarItemMockComponent }
]
这有什么问题吗?为什么在单元测试中找不到 BsNavbarItemComponent
提供程序?
模块提供程序未被注入,因为 @Host
注入注解。
因此您的模拟组件应该可以通过原始组件令牌注入
@Component({
selector: 'bs-navbar-item',
template: `
<li>
<ng-content></ng-content>
</li>`,
providers: [provide: BsNavbarItemComponent, useExisting: forwardRef(() => BsNavbarItemMockComponent)]
})
class BsNavbarItemMockComponent {
}
我正在创建自己的 angular bootstrap library,目前我一直在为导航栏编写单元测试。
我提炼了 the troubled unit test down to the bare essentials 以下是摘要:
单元测试
describe('BsNavbarDropdownComponent', () => {
let component: BsNavbarDropdownTestComponent;
let fixture: ComponentFixture<BsNavbarDropdownTestComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([])
],
declarations: [
// Component to test
BsNavbarDropdownComponent,
// Mock components
BsNavbarItemMockComponent,
// Testbench
BsNavbarDropdownTestComponent
],
providers: [
{ provide: BsNavbarItemComponent, useClass: BsNavbarItemMockComponent }
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(BsNavbarDropdownTestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@Component({
selector: 'bs-navbar-test',
template: `
<bs-navbar-item>
<a [routerLink]='[]'>dropdown</a>
<bs-navbar-dropdown>
<bs-navbar-item>
<a [routerLink]='["/b", "c"]'>bc</a>
</bs-navbar-item>
</bs-navbar-dropdown>
</bs-navbar-item>`
})
class BsNavbarDropdownTestComponent {
}
@Component({
selector: 'bs-navbar-item',
template: `
<li>
<ng-content></ng-content>
</li>`
})
class BsNavbarItemMockComponent {
}
待测单元
@Component({
selector: 'bs-navbar-dropdown',
templateUrl: './navbar-dropdown.component.html',
styleUrls: ['./navbar-dropdown.component.scss']
})
export class BsNavbarDropdownComponent {
constructor(
@Host() @Inject(forwardRef(() => BsNavbarItemComponent)) navbarItem: BsNavbarItemComponent
) {
this.navbarItem = navbarItem;
}
navbarItem: BsNavbarItemComponent;
}
在 BsNavbarDropdownTestComponent
中,显然 bs-navbar-dropdown
(BsNavbarDropdownComponent
) 有一个父标签 bs-navbar-item
(BsNavbarItemMockComponent
)。在要测试的单元中,我正在注入 BsNavbarItemComponent
,它在作为 BsNavbarItemMockComponent
.
不过单元测试好像还是没有成功。
npm run nx run-many -- --target=test --projects=ng-bootstrap-demo --with-deps --watch=false --browsers=ChromeHeadless
结果:
FAIL xxx-ng-bootstrap libs/xxx-ng-bootstrap/src/lib/components/navbar/navbar-dropdown/navbar-dropdown.component.spec.ts
● BsNavbarDropdownComponent › should create
NG0201: No provider for BsNavbarItemComponent found in NodeInjector. Find more at https://angular.io/errors/NG0201
同样,请注意该模块具有以下供应商:
providers: [
{ provide: BsNavbarItemComponent, useClass: BsNavbarItemMockComponent }
]
这有什么问题吗?为什么在单元测试中找不到 BsNavbarItemComponent
提供程序?
模块提供程序未被注入,因为 @Host
注入注解。
因此您的模拟组件应该可以通过原始组件令牌注入
@Component({
selector: 'bs-navbar-item',
template: `
<li>
<ng-content></ng-content>
</li>`,
providers: [provide: BsNavbarItemComponent, useExisting: forwardRef(() => BsNavbarItemMockComponent)]
})
class BsNavbarItemMockComponent {
}