我想测试一个函数。要在单元测试中调用该函数,我需要创建组件类的一个实例。组件类在构造函数中包含不同的服务作为参数,包括服务CookieService。该服务依赖于第三个库'ngx-cookie',它有setter和getter。
我尝试模拟服务,以便能够像这样创建组件类的实例:
import {CookieService} from "ngx-cookie-service";
....
beforeEach(async(() => {
const mockedFormBuilder = jasmine.createSpyObj('FormBuilder', ['control', 'array', 'group']);
const get = function get(name: string): string {
return 'test...';
};
TestBed.configureTestingModule({
declarations: [HelloWorldComponent,...],
imports: [
...
],
providers: [
{provide: FormBuilder, useValue: mockedFormBuilder},
{provide: CookieService, useValue: get('name')},
]
})
.compileComponents();
}));
describe('getArr', () => {
it('should return array', () => {
const text = 'text@domain.com';
const textArr = ['text@domain.com']
let getArr: string[];
// @ts-ignore
getArr = new HelloWorldComponent(FormBuilder,CookieService).getTextArray(tex);
expect(getArr).toBe(textArr);
})
})
运行测试时出现以下错误:
TypeError: this.cookieService.get is not a function
at <Jasmine>
at new HelloWorldComponent(http://localhost:9876/_karma_webpack_/src/app/helloworld.component.ts:63:51)
at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/helloworld.component.spec.ts:113:28)
at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:359:1)
at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:308:1)
at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:358:1)
at Zone.run (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:124:1)
at runInTestZone (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:561:1)
at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:576:1)
ComponentClass是这样的:
export class HelloWorldComponent {
constructor(private fb: FormBuilder, private cookieService:CookieService){
const cookie:string=this.cookieService.get('somename')
}
}
我知道cookieService没有函数,只有一个getter和setter,但我不太明白如何模拟getter以及如何正确地将其插入到提供者
是否有人在测试时遇到了同样的错误,你是如何解决的?
任何帮助将非常感激!
更新:使用存根服务
export class CookieServiceStub{
cookie:string= 'gdhjgsfgsjdfg';
get (name:string):string{
return this.cookie;
}
}
在Spec文件中:…
TestBed.configureTestingModule({
declarations: [HelloWorldComponent,...],
imports: [
...
],
providers: [
{provide: FormBuilder, useValue: mockedFormBuilder},
{provide: CookieService, useClass:CookieServiceStub},
]
})
.compileComponents();
}));
您目前正在提供调用get('name')
的结果作为CookieService服务的值。我认为这是不正确的……:
{provide: CookieService, useValue: get('name')}
在这种情况下,创建Stub类要简单一些:
首先在你的组件中画出你从服务中调用的函数,然后为它创建一个Stub类:
class CookieServiceStub{
get(name: string) {
return 'your value'
}
secondFunction() {}
// add as many as necessary
}
然后你可以用你的存根类替换你的CookieService提供:
{provide: CookieService, useClass: CookieServiceStub}
同样在你的测试中,你正在创建一个组件类的新实例,超出了angular的作用域,这需要进行调整。而不是这样做:
getArr = new HelloWorldComponent(FormBuilder,CookieService).getTextArray(tex);
你应该用TestBed:
创建它...
let component: HelloWorldComponent;
beforeEach(() => {
fixture = TestBed.createComponent(HelloWorldComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
describe('getArr', () => {
it('should return array', () => {
const text = 'text@domain.com';
const textArr = ['text@domain.com']
let getArr: string[];
getArr = component.getTextArray(tex);
expect(getArr.length).toBe(1);
expect(getArr[0]).toBe(text);
})
})
...
jasmine.createSpyObj用于创建监视方法的模拟。它将为spy中定义的每个属性返回一个对象。
你可以创建一个mockCookieService并添加get
方法
mockCookieService = jasmine.createSpyObj('CookieService', ['get']);
试试:
describe('Service: ', () => {
let mockCookieService;
beforeEach(() => {
mockCookieService = jasmine.createSpyObj('CookieService', ['get']);
TestBed.configureTestingModule({
imports: [
...
],
providers: [
{ provide: CookieService, useValue: mockCookieService },
]
});
});
你可以参考这篇文章