如何在 Angular 中为单元测试模拟父 class 方法?
How to mock parent class method for Unit Test in Angular?
我正在为 class 编写单元测试,它扩展了另一个 class 并在运行时调用父方法。因为我不想处理父 class 有什么办法可以模拟该方法调用吗?我尝试了多种方法,但没有任何效果
class A {
doSomething(){
console.log(123);
}
}
class B extends A {
work(){
this.doSomething();
}
}
如何在 Class B 的单元测试中模拟此函数调用和 return 其他内容?
我尝试了以下方法:
spyOn(b,'doSomething');
spyOn(Object.getPrototypeOf(b),'doSomething');
没有错误就是一直调用原来的父方法
你可以做的,但我不推荐它,是将父方法本身存根在你的内部 class B.
我不推荐这种方法,因为您会在 Class 单元测试中添加一些东西。我宁愿在这个父方法中完成一些事情。
但是如果你真的想存根那个方法,你可以按照这些思路做一些事情:
describe('DataService', () => {
let service: DataService;
beforeEach(async(() => {
TestBed.configureTestingModule({ providers: [DataService] });
}));
beforeEach(() => {
service = TestBed.get(DataService); // would be inject in newer angular versions
});
it('test case 2', () => {
spyOn(service as any, 'parentMethod').and.returnValue(5);
expect(service.getData()).toEqual(5);
});
});
其中 DataService
会是
@Injectable({
providedIn: 'root'
})
export class DataService extends AbstractDataService {
constructor() {
super();
}
getData() {
return this.parentMethod();
}
}
和AbstractDataService
@Injectable({
providedIn: 'root'
})
export class AbstractDataService {
constructor() { }
parentMethod() {
console.log('parent method');
return null;
}
}
也适用于组件。但同样:不建议在被测对象内部模拟方法!!
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppComponent, AbstractAppComponent],
schemas: [NO_ERRORS_SCHEMA],
bootstrap: [AppComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
it('should mock method', () => {
spyOn(component as any, 'abstractMethod').and.returnValue(10);
fixture.detectChanges();
expect(component.myMethod()).toEqual(10);
});
});
我正在为 class 编写单元测试,它扩展了另一个 class 并在运行时调用父方法。因为我不想处理父 class 有什么办法可以模拟该方法调用吗?我尝试了多种方法,但没有任何效果
class A {
doSomething(){
console.log(123);
}
}
class B extends A {
work(){
this.doSomething();
}
}
如何在 Class B 的单元测试中模拟此函数调用和 return 其他内容?
我尝试了以下方法:
spyOn(b,'doSomething');
spyOn(Object.getPrototypeOf(b),'doSomething');
没有错误就是一直调用原来的父方法
你可以做的,但我不推荐它,是将父方法本身存根在你的内部 class B.
我不推荐这种方法,因为您会在 Class 单元测试中添加一些东西。我宁愿在这个父方法中完成一些事情。
但是如果你真的想存根那个方法,你可以按照这些思路做一些事情:
describe('DataService', () => {
let service: DataService;
beforeEach(async(() => {
TestBed.configureTestingModule({ providers: [DataService] });
}));
beforeEach(() => {
service = TestBed.get(DataService); // would be inject in newer angular versions
});
it('test case 2', () => {
spyOn(service as any, 'parentMethod').and.returnValue(5);
expect(service.getData()).toEqual(5);
});
});
其中 DataService
会是
@Injectable({
providedIn: 'root'
})
export class DataService extends AbstractDataService {
constructor() {
super();
}
getData() {
return this.parentMethod();
}
}
和AbstractDataService
@Injectable({
providedIn: 'root'
})
export class AbstractDataService {
constructor() { }
parentMethod() {
console.log('parent method');
return null;
}
}
也适用于组件。但同样:不建议在被测对象内部模拟方法!!
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppComponent, AbstractAppComponent],
schemas: [NO_ERRORS_SCHEMA],
bootstrap: [AppComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
it('should mock method', () => {
spyOn(component as any, 'abstractMethod').and.returnValue(10);
fixture.detectChanges();
expect(component.myMethod()).toEqual(10);
});
});