如何在 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);
    });    
});

Stackblitz with test cases for both service and component