What you could do, but I would not recommend it, is to stub the parent method itself inside you class B.
I would not recommend this approach because you would stub something inside the Class you are unit testing. I would rather stub things, that are being done inside this parent method.
But if you really want to stub that method, you could do something along those lines:
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);
});
});
where DataService would be
@Injectable({
providedIn: 'root'
})
export class DataService extends AbstractDataService {
constructor() {
super();
}
getData() {
return this.parentMethod();
}
}
and AbstractDataService
@Injectable({
providedIn: 'root'
})
export class AbstractDataService {
constructor() { }
parentMethod() {
console.log('parent method');
return null;
}
}
Works for components, too. But again: it is not advisable to mock methods inside the object under test!!
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);
});
});
Stackblitz with test cases for both service and component