如何单元测试Angular的元服务?
我的组件是在ngoninit
期间使用Angular的Meta服务更新元标记。我正在使用我的grounionservice
获取App-ID,并通过模板文字使用Meta的UpdateTag
方法设置它。但是我的单位测试是在模板字面的我的grounionservice
设置的值时遇到问题。该测试返回以下错误:
Expected spy Meta.updateTag to have been called with:
[ Object({ name: 'apple-itunes-app', content: 'app-id=0123456789' }) ]
but actual calls were:
[ Object({ name: 'apple-itunes-app', content: 'app-id=undefined' }) ].
我如何修改测试,以便知道值app-id
,由我的模板literal $ {this.gregionservice.getAppid()} ?
my.component.ts
import { Component, OnInit } from '@angular/core';
import { RegionService } from 'src/services/region.service';
import { Meta } from '@angular/platform-browser';
export class MyComponent implements OnInit {
constructor(
private regionService: RegionService,
private meta: Meta
) {}
ngOnInit() {
this.meta.updateTag({name: 'apple-itunes-app', content: `app-id=${this.regionService.getAppId()}`});
}
}
my.component.spec.ts
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MyComponent } from './my.component';
import { RegionService } from 'src/services/region.service';
import { Meta } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
let regionServiceSpy: jasmine.SpyObj<RegionService>;
let metaServiceSpy: jasmine.SpyObj<Meta>;
beforeEach(
waitForAsync(() => {
const regionServiceSpyObj = jasmine.createSpyObj('RegionService', ['getAppId', 'retrieveABCRegions', 'retrieveDEFRegions']);
const metaServiceSpyObj = jasmine.createSpyObj('Meta', ['updateTag']);
TestBed.configureTestingModule({
declarations: [MyComponent],
imports: [RouterTestingModule],
providers: [
{ provide: RegionService, useValue: regionServiceSpyObj },
{ provide: Meta, useValue: metaServiceSpyObj },
],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();
regionServiceSpy = TestBed.inject(RegionService) as jasmine.SpyObj<RegionService>;
metaServiceSpy = TestBed.inject(Meta) as jasmine.SpyObj<Meta>;
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should set app-id to 0123456789 if selectedRegion is FR', () => {
// arrange
// act
regionServiceSpy.selectedRegion = 'FR';
// assert
expect(metaServiceSpy.updateTag).toHaveBeenCalledWith({name: 'apple-itunes-app', content: 'app-id=0123456789'});
});
});
region.service.ts
import { retrieveABCRegions, retrieveDEFRegions} from 'src/regions';
@Injectable({
providedIn: 'root',
})
export class RegionService {
selectedRegion: Region;
getAppId(): string {
if (retrieveABCRegions().includes(this.selectedRegion)) {
return '111111111';
} else if (retrieveDEFRegions().includes(this.selectedRegion)) {
return '0123456789';
}
}
}
My Component is using Angular's Meta service to update a meta tag during ngOnInit
. I'm using my RegionService
to get an app-id and set it with Meta's updateTag
method via a template literal. But my unit test is having problems getting the value set by my RegionService
in the template literal. The test returns the following error:
Expected spy Meta.updateTag to have been called with:
[ Object({ name: 'apple-itunes-app', content: 'app-id=0123456789' }) ]
but actual calls were:
[ Object({ name: 'apple-itunes-app', content: 'app-id=undefined' }) ].
How can I modify my test so that it knows the value app-id
, set by my template literal ${this.regionService.getAppId()}
?
my.component.ts
import { Component, OnInit } from '@angular/core';
import { RegionService } from 'src/services/region.service';
import { Meta } from '@angular/platform-browser';
export class MyComponent implements OnInit {
constructor(
private regionService: RegionService,
private meta: Meta
) {}
ngOnInit() {
this.meta.updateTag({name: 'apple-itunes-app', content: `app-id=${this.regionService.getAppId()}`});
}
}
my.component.spec.ts
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MyComponent } from './my.component';
import { RegionService } from 'src/services/region.service';
import { Meta } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
let regionServiceSpy: jasmine.SpyObj<RegionService>;
let metaServiceSpy: jasmine.SpyObj<Meta>;
beforeEach(
waitForAsync(() => {
const regionServiceSpyObj = jasmine.createSpyObj('RegionService', ['getAppId', 'retrieveABCRegions', 'retrieveDEFRegions']);
const metaServiceSpyObj = jasmine.createSpyObj('Meta', ['updateTag']);
TestBed.configureTestingModule({
declarations: [MyComponent],
imports: [RouterTestingModule],
providers: [
{ provide: RegionService, useValue: regionServiceSpyObj },
{ provide: Meta, useValue: metaServiceSpyObj },
],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();
regionServiceSpy = TestBed.inject(RegionService) as jasmine.SpyObj<RegionService>;
metaServiceSpy = TestBed.inject(Meta) as jasmine.SpyObj<Meta>;
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should set app-id to 0123456789 if selectedRegion is FR', () => {
// arrange
// act
regionServiceSpy.selectedRegion = 'FR';
// assert
expect(metaServiceSpy.updateTag).toHaveBeenCalledWith({name: 'apple-itunes-app', content: 'app-id=0123456789'});
});
});
region.service.ts
import { retrieveABCRegions, retrieveDEFRegions} from 'src/regions';
@Injectable({
providedIn: 'root',
})
export class RegionService {
selectedRegion: Region;
getAppId(): string {
if (retrieveABCRegions().includes(this.selectedRegion)) {
return '111111111';
} else if (retrieveDEFRegions().includes(this.selectedRegion)) {
return '0123456789';
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于您已用
gemionservice
spyobj
模拟:实际服务不再在测试中使用(这是正确的方法,因为您没有测试该测试在这里服务)。
因此,现在您需要定义模拟服务的
getAppid()
方法将返回什么值。您可以通过在间谍对象上为该方法创建间谍策略来做到这一点。有不同类型的间谍策略最简单的是
returnValue()
:并注意设置
gecionservicespy.seledectegion ='fr'
不是在这里需要,因为没有调用实际的服务方法。Since you've replaced the
RegionService
with aSpyObj
mock:the real service is no longer being used in your tests (which is the correct approach because you're not testing that service here).
So now you need to define what value the mock service's
getAppId()
method is going to return. You do that by creating a spy strategy for that method on your spy object.There are different types of spy strategies you can use, but for your purposes here, probably the simplest is
returnValue()
:And note that setting
regionServiceSpy.selectedRegion = 'FR'
is not needed here since the actual service method is not being called.