Javascript 如何在每次测试之间改变spy结果
我正在为一个依赖于服务的角度组件编写一些测试 此服务有一个Javascript 如何在每次测试之间改变spy结果,javascript,angular,unit-testing,jasmine,Javascript,Angular,Unit Testing,Jasmine,我正在为一个依赖于服务的角度组件编写一些测试 此服务有一个stageData公共成员,我想根据stageData的内容测试组件是否正常工作 因为我需要模拟该服务,所以我创建了一个spy并定义了它将返回给stageData的内容,但我无法在每次测试中更改它 describe('ProgressComponent', () => { let component: ProgressComponent; let fixture: ComponentFixture<ProgressCo
stageData
公共成员,我想根据stageData
的内容测试组件是否正常工作
因为我需要模拟该服务,所以我创建了一个spy并定义了它将返回给stageData的内容,但我无法在每次测试中更改它
describe('ProgressComponent', () => {
let component: ProgressComponent;
let fixture: ComponentFixture<ProgressComponent>;
let progressStageService: any;
const signStage = new StageCompletionModel();
const inkStage = new StageCompletionModel();
beforeEach(async(() => {
signStage.stage = Stage.Sign;
inkStage.stage = Stage.Ink;
progressStageService = jasmine.createSpyObj('ProgressStageService', ['getStageProgress']);
progressStageService.stageData = [signStage];
TestBed.configureTestingModule({
declarations: [ ProgressComponent ],
providers: [ { provide: ProgressStageService, useValue: progressStageService } ],
schemas: [ NO_ERRORS_SCHEMA ],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProgressComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should not display Ink stage when it is not in stageData', () => {
const callToAction: HTMLElement = fixture.nativeElement;
const stageLabels = callToAction.querySelectorAll('span.stage-label');
expect(Array.from(stageLabels).some(sl => sl.textContent.includes('Ink'))).toBeFalsy();
});
it('should display Ink stage when it is in stageData', () => {
const callToAction: HTMLElement = fixture.nativeElement;
const stageLabels = callToAction.querySelectorAll('span.stage-label');
progressStageService.stageData = [signStage, inkStage];
fixture.detectChanges();
expect(Array.from(stageLabels).some(sl => sl.textContent.includes('Ink'))).toBeTruthy();
});
});
description('ProgressComponent',()=>{
let组件:ProgressComponent;
let夹具:组件夹具;
让ProgressStage服务:任何;
const signStage=new StageCompletionModel();
const inkStage=new StageCompletionModel();
beforeach(异步(()=>{
signStage.stage=stage.Sign;
inkStage.stage=stage.Ink;
progressStageService=jasmine.createSpyObj('progressStageService',['getStageProgress']);
progressStageService.stageData=[signStage];
TestBed.configureTestingModule({
声明:[ProgressComponent],
提供程序:[{提供:ProgressStageService,useValue:ProgressStageService}],
模式:[无错误模式],
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(ProgressComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
});
它('不在stageData中时不应显示墨水阶段',()=>{
const callToAction:HTMLElement=fixture.nativeElement;
const stageLabels=callToAction.querySelectorAll('span.stage标签');
expect(Array.from(stagelables).some(sl=>sl.textContent.includes('Ink')).toBeFalsy();
});
它('在stageData中时应显示墨水阶段',()=>{
const callToAction:HTMLElement=fixture.nativeElement;
const stageLabels=callToAction.querySelectorAll('span.stage标签');
progressStageService.stageData=[signStage,inkStage];
fixture.detectChanges();
expect(Array.from(stagelables).some(sl=>sl.textContent.includes('Ink')).toBeTruthy();
});
});
我在第二个测试用例中尝试了许多变体,但stageData始终包含在每次之前在
中设置的数据,因此在模拟数据时,您必须将其拆分为更多的描述。第一个fixture.detectChanges
在第二个beforeach
中是“捆绑”组件并调用ngOnInit
的
尝试:
description('ProgressComponent',()=>{
let组件:ProgressComponent;
let夹具:组件夹具;
让ProgressStage服务:任何;
const signStage=new StageCompletionModel();
const inkStage=new StageCompletionModel();
beforeach(异步(()=>{
signStage.stage=stage.Sign;
inkStage.stage=stage.Ink;
progressStageService=jasmine.createSpyObj('progressStageService',['getStageProgress']);
TestBed.configureTestingModule({
声明:[ProgressComponent],
提供程序:[{提供:ProgressStageService,useValue:ProgressStageService}],
模式:[无错误模式],
})
.compileComponents();
}));
在每个之前(()=>{
log('在夹具上获得手柄');
fixture=TestBed.createComponent(ProgressComponent);
控制台日志(夹具);
组件=fixture.componentInstance;
//将progressStageService重新分配给configureTestingModule中注入的内容
//如果你用的是Angular 9,这应该是。注入而不是。获取
progressStageService=TestBed.get(progressStageService);
//fixture.detectChanges();=>在此处移除fixture.detectChanges
});
描述('stageData为[signStage]”,()=>{
在每个之前(()=>{
//将stageData分配给注入的服务
progressStageService.stageData=[signStage];
fixture.detectChanges();
});
它('不在stageData中时不应显示墨水阶段',()=>{
const callToAction:HTMLElement=fixture.nativeElement;
const stageLabels=callToAction.querySelectorAll('span.stage标签');
expect(Array.from(stagelables).some(sl=>sl.textContent.includes('Ink')).toBeFalsy();
});
});
描述('stageData是[signStage,inkStage],()=>{
在每个之前(()=>{
//将stageData分配给注入的服务
progressStageService.stageData=[signStage,inkStage];
fixture.detectChanges();
});
它('在stageData中时应显示墨水阶段',()=>{
const callToAction:HTMLElement=fixture.nativeElement;
const stageLabels=callToAction.querySelectorAll('span.stage标签');
expect(Array.from(stagelables).some(sl=>
sl.textContent.includes('Ink')).toBeTruthy();
});
});
});
我收到一个错误,在ProgressComponent中stageData未定义,而在我的测试中fixture未定义。在获取fixture上的句柄之前,我添加了两个控制台.log
s。确保它们在执行测试时运行。至于stageData
在ProgressComponent
中未定义,我认为stageData
生活在ProgressStageService
?对不起,我的意思是,stageData
在ProgressComponent
中从ProgressStageService
使用时未定义。我添加了两个console.log语句。第一个正在工作,但是第二个没有被调用,即使我在语句中放了一个字符串。我还在控制台zone evergreen.js:2857 GET ng:///ProgressComponent/%C9%B5fac.js net::ERR\u UNKNOWN\u URL\u SCHEME
中遇到此错误。目前正在调查。我可以通过设置progressStageService.stageData=[]来消除错误代码>在每个之前的第一个中
但是我又回到了它不更新的时候。我想我可以写两个独立的descripe
s。它很难看,但我无法让它工作。第二个名字不被调用的方式很奇怪,但是是的,尝试两个不同的描述。我提出的“应该”是两种不同的描述
describe('ProgressComponent', () => {
let component: ProgressComponent;
let fixture: ComponentFixture<ProgressComponent>;
let progressStageService: any;
const signStage = new StageCompletionModel();
const inkStage = new StageCompletionModel();
beforeEach(async(() => {
signStage.stage = Stage.Sign;
inkStage.stage = Stage.Ink;
progressStageService = jasmine.createSpyObj('ProgressStageService', ['getStageProgress']);
TestBed.configureTestingModule({
declarations: [ ProgressComponent ],
providers: [ { provide: ProgressStageService, useValue: progressStageService } ],
schemas: [ NO_ERRORS_SCHEMA ],
})
.compileComponents();
}));
beforeEach(() => {
console.log('getting a handle on the fixture');
fixture = TestBed.createComponent(ProgressComponent);
console.log(fixture);
component = fixture.componentInstance;
// re-assign progressStageService to what was injected in the configureTestingModule
// If you're using Angular 9, this should be .inject and not .get
progressStageService = TestBed.get(ProgressStageService);
// fixture.detectChanges(); => Remove fixture.detectChanges here
});
describe('stageData is [signStage]', () => {
beforeEach(() => {
// assign stageData to the service that was injected
progressStageService.stageData = [signStage];
fixture.detectChanges();
});
it('should not display Ink stage when it is not in stageData', () => {
const callToAction: HTMLElement = fixture.nativeElement;
const stageLabels = callToAction.querySelectorAll('span.stage-label');
expect(Array.from(stageLabels).some(sl => sl.textContent.includes('Ink'))).toBeFalsy();
});
});
describe('stageData is [signStage, inkStage]', () => {
beforeEach(() => {
// assign stageData to the service that was injected
progressStageService.stageData = [signStage, inkStage];
fixture.detectChanges();
});
it('should display Ink stage when it is in stageData', () => {
const callToAction: HTMLElement = fixture.nativeElement;
const stageLabels = callToAction.querySelectorAll('span.stage-label');
expect(Array.from(stageLabels).some(sl =>
sl.textContent.includes('Ink'))).toBeTruthy();
});
});
});