angular - Angular selectRootElement 适用于应用程序而不是测试
问题描述
我的 Angular 应用程序要求通过以下方式将数据传递给页面上的根组件:
<application-root testVar="hello world"></application-root>
经过大量研究,我决定不使用 ElementRef 来访问该属性,而是使用 Renderer2。我的 AppComponent 的构造函数设置如下:
@Component({
selector: 'application-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
public data: string;
constructor(private renderer: Renderer2)
{
this.data = this.renderer.selectRootElement('application-root', true).getAttribute('testVar');
}
..
}
当我在我的应用程序中运行它时,我没有收到任何错误,并且我得到了值“hello world”。但是,当我尝试运行单元测试用例时,出现以下错误:“选择器“application-root”与任何元素都不匹配”。这是我的测试用例:
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
HttpClientTestingModule
],
declarations: [
AppComponent
],
providers: [
{provide: Router, useValue: routerSpy},
Renderer2
]
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
}));
it('should create the app', () => {
expect(fixture).toBeTruthy();
});
现在,如果我将 selectRootElement 调用移出构造函数,并移入 ngOnInit() 函数,我的单元测试用例通过,但是当我尝试运行应用程序时,我得到一个空白屏幕。
我需要在我的代码中做什么才能访问可以在我的应用程序中正确运行并通过单元测试用例的根组件属性?
解决方案
所以我想出的解决方案是将所有内容从构造函数中移出并放入 ngOnInit() 函数中。当我重新测试运行应用程序时,它确实有效,屏幕上没有任何内容。然而,为了使这与单元测试用例一起工作,我了解到我必须在 beforeEach 函数中添加元素本身。
当 Angular 使用 AppComponent 执行其单元测试用例时,被渲染的模板是一个标签,而不是我们都知道的选择器。因此,为了让应用程序获取该元素,我们将首先创建它,然后为该元素设置属性,这样当测试脚本运行时,它将识别模板中的该元素:
let appElement: ElementRef;
let renderer2: Renderer2;
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
HttpClientTestingModule
],
declarations: [
AppComponent
],
providers: [
{provide: Router, useValue: routerSpy},
Renderer2
]
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
renderer2 = fixture.componentRef.injector.get<Renderer2>(Renderer2 as Type<Renderer2>);
appElement = renderer2.createElement('application-root');
renderer2.appendChild(fixture.nativeElement, appElement);
component = fixture.componentInstance;
}));
it('should create the app', () => {
expect(fixture).toBeTruthy();
});
如果有更好的方法来解决这个问题,我会全力以赴。
推荐阅读
- c# - .net core 5 和 .net framework 4.7.2 的跨框架项目
- ios - Error "library not found for lswiftXCTest" when I try to run the tests
- python-3.x - How to create custom python automation API for Kapacitor container?
- javascript - Using context with React to pass values between components
- r - 根据 T/F 列仅粘贴向量的一部分
- javascript - 使用 Konva 向压缩圆可视化添加缩放(从中心缩放和重新定位)
- c# - 向记录添加数字以避免 HashSet 中的重复值
- c++ - 强制失败通用模板但允许专业化,加上“方法存在调度”
- swift - 使用 Alamofire 访问 Localhost API
- devops - 当工作项在 Devops 中更改为完成时,如何创建共享点列表项?