[英]How to inject Input() in unit testing?
So i try to do some unit testing on a component.所以我尝试对一个组件进行一些单元测试。 But I have some problems with Input() parameter.
但是我对 Input() 参数有一些问题。 And then especially a component in the component
然后特别是组件中的一个组件
SO I have this component:所以我有这个组件:
export class EcheqDisplayComponent implements OnInit {
echeq: EcheqSubmissionApi;
constructor(
private route: ActivatedRoute
) {
this.echeq = this.route.snapshot.data['submission'];
}
ngOnInit() {
}
getAnswers(page: EcheqPageApi): any[] {
return page.elements.map(element => this.echeq.answers[element.name]);
}
}
and the template:和模板:
<div class="echeq-display" *ngIf="echeq">
<header class="echeq-display-header header">
<div class="echeq-display-info">
<h1 class="heading echeq-display-heading">
{{ echeq.definition.title }}
</h1>
<div class="sub-heading echeq-display-subheading">
<span class="echeq-display-creator">
Toegekend door:
{{ echeq.assignedByProfName ? echeq.assignedByProfName : 'Het Systeem' }}
</span>
<span class="echeq-display-date">{{
echeq.definition.createdOnUtc | date: 'dd MMM'
}}</span>
</div>
</div>
<app-meta-box
[metadata]="{
numPages: echeq.definition.numPages,
vPoints: echeq.definition.awardedVPoints
}"
></app-meta-box>
</header>
<main class="echeq-display-questions body">
<app-echeq-question
*ngFor="let page of echeq.definition.pages; let i = index"
[page]="page"
[readonly]="true"
[number]="i + 1"
[answers]="getAnswers(page)"
></app-echeq-question>
</main>
</div>
and the unit test:和单元测试:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { EcheqDisplayComponent } from './echeq-display.component';
import { ParticipantEcheqModule } from '../../participant-echeq.module';
import { RouterModule, ActivatedRoute } from '@angular/router';
import { MockActivatedRoute } from 'src/app/shared/mocks/MockActivatedRoute';
import { MetaData } from '../meta-box/meta-box.component';
describe('EcheqDisplayComponent', () => {
let component: EcheqDisplayComponent;
let fixture: ComponentFixture<EcheqDisplayComponent>;
const metaData: MetaData = new MetaData();
// const metaDataInfo = fixture.debugElement.componentInstance;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ],
providers: [
{ provide: ActivatedRoute, useClass: MockActivatedRoute }
],
imports:[
ParticipantEcheqModule
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EcheqDisplayComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
fit('should create component', () => {
metaData.numPages = 20;
expect(component).toBeTruthy();
});
});
But it stay saying:但它一直在说:
TypeError: Cannot read property 'numPages' of undefined. TypeError:无法读取未定义的属性“numPages”。
So what I have to change that it is working?那么我必须改变它的工作原理吗?
Thank you谢谢
So the MetaData is from the app-meta-box component.it looks like this:所以 MetaData 来自 app-meta-box 组件。它看起来像这样:
export class MetaData {
numPages: number;
vPoints: number;
}
@Component({
selector: 'app-meta-box',
templateUrl: './meta-box.component.html',
styleUrls: ['./meta-box.component.scss']
})
export class MetaBoxComponent implements OnInit {
@Input() metadata: MetaData;
constructor() {}
ngOnInit() {}
}
This is the mock class:这是模拟 class:
export class MockActivatedRoute {
public snapshot = {
data: {
submission: {
answers: {}
}
}
};
}
I have it now like this:我现在有这样的:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { EcheqDisplayComponent } from './echeq-display.component';
import { ParticipantEcheqModule } from '../../participant-echeq.module';
import { RouterModule, ActivatedRoute } from '@angular/router';
import { MockActivatedRoute } from 'src/app/shared/mocks/MockActivatedRoute';
import { MetaData } from '../meta-box/meta-box.component';
describe('EcheqDisplayComponent', () => {
let component: EcheqDisplayComponent;
let fixture: ComponentFixture<EcheqDisplayComponent>;
const metaData: MetaData = new MetaData();
// const metaDataInfo = fixture.debugElement.componentInstance;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ],
providers: [
{ provide: ActivatedRoute, useValue: new MockActivatedRoute().withData({submission:{ answers:{} } }) }
],
imports:[
ParticipantEcheqModule
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EcheqDisplayComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
fit('should create component', () => {
component.echeq = {
definition: {
title: 'test title',
awardedVPoints: 0,
numPages: 9
}
}
expect(component).toBeTruthy();
});
});
But then I get this error:
Property 'answers' is missing in type '{ definition: { title: string; awardedVPoints: number; numPages: number; }; }' but required in type 'EcheqSubmissionApi'.ts(2741)
echeqSubmissionApi.ts(59, 5): 'answers' is declared here.
I have it now like this:我现在有这样的:
fit('should create component', () => {
component.echeq = {
definition: {
title: 'test title',
awardedVPoints: 0,
numPages:9
}
} as EcheqSubmissionApi;
expect(component).toBeTruthy();
});
export interface EcheqSubmissionApi {
/**
* Primary key of this submission (server set).
*/
id?: string;
definition?: EcheqDefinitionApi;
/**
* Id of the prof who assigned this eCheq (server set).
*/
assignedByProfId?: string;
/**
* Name of the prof who assigned this eCheq (server set). Only set on get operations. May be null if assigned by the system.
*/
assignedByProfName?: string;
/**
* Id of the organisation who assigned this eCheq (server set).
*/
assignedByOrgId?: number;
/**
* Participant ID of the patient this eCheq is assigned to (server set).
*/
assignedToId?: string;
/**
* When this submission was assigned (UTC, server set).
*/
assignedOnUtc?: Date;
/**
* If set until when the eCheq can be submitted.
*/
validUntilUtc?: Date;
/**
* Whether the eCheq has been started and whether it has been submitted (server set).
*/
status?: EcheqSubmissionApi.StatusEnum;
/**
* When this submission was completed (UTC, server set).
*/
submittedOnUtc?: Date;
/**
* Answers of form. In the form of a json object with name and value of the questions { \"nameOfQuestion\" : \"valueOfQuestion\" }
*/
answers: object;
/**
* initialValues of form. In the form of a json object with name and value of variables { \"nameOfQuestion\" : \"valueOfQuestion\" }
*/
initialValues?: object;
/**
* The page the participant is currently on
*/
currentPage?: number;
/**
* The progress of the echeq in percentage
*/
progress?: number;
}
export namespace EcheqSubmissionApi {
export type StatusEnum = 'New' | 'Active' | 'Submitted';
export const StatusEnum = {
New: 'New' as StatusEnum,
Active: 'Active' as StatusEnum,
Submitted: 'Submitted' as StatusEnum
};
}
But if I run the unit test, I still get this error:但是,如果我运行单元测试,我仍然会收到此错误:
TypeError: Cannot read property 'numPages' of undefined
To answer your question:要回答您的问题:
component.metadata = /// whatever you want this to be
You have your error with numPages: echeq.definition.numPages
.您对
numPages: echeq.definition.numPages
有错误。 Endeed, echeq
is also undefined. Endeed,
echeq
也是未定义的。
You can try:你可以试试:
component.echeq = {
definition: {
numPages: 9
}
}
Or better way would be to returns this value from this.route.snapshot.data['submission'];
或者更好的方法是从
this.route.snapshot.data['submission'];
返回这个值。 so from MockActivatedRoute
所以从
MockActivatedRoute
UPDATE :更新:
And update MockActivatedRoute
to allows dynamic parameters:并更新
MockActivatedRoute
以允许动态参数:
export class MockActivatedRoute {
snapshot = {
data: {}
};
constructor(){}
withData(data:any): MockActivatedRoute {
this.snapchot.data = data;
return this;
}
}
So now in your test, you can use it:所以现在在你的测试中,你可以使用它:
{ provide: ActivatedRoute, useValue: new MockActivatedRoute().withData({submission:{ answers:{} } }) }
No problem.没问题。 It was an easy:
这很容易:
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
],
imports:[
ParticipantEcheqModule,
RouterTestingModule
]
})
.compileComponents();
}));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.