我有一个可扩展的服务(EntityApi),它扩展了一个类(BaseApi)。在我的规范中,我喜欢使用BaseApiStub模拟BaseApi。但这是徒劳的。始终调用EntityApi。

// class
export class BaseApi { // want to mock BaseApi
    constructor(injector: Injector) {
       console.log("Should not be here...");
    }
}

// service
@Injectable()
export class EntityApi extends BaseApi {
    constructor(injector: Injector) {
       super(injector, "entity");
    }
}

// component
@Component({
  selector: 'rt-entity-list',
  templateUrl: './entity-list.component.html',
})
export class EntityListComponent {
  api: any;
  constructor(public entityApi: EntityApi) {
    this.api = entityApi;
  }
}

// mock api
export class BaseApiStub { //mocked api
    constructor() {
      console.log("You are on track!!")
    }
    get() { }
}

// spec
describe('EntityListComponent', () => {
  let component: EntityListComponent;
  let fixture: ComponentFixture<EntityListComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [EntityListComponent],
      providers: [ { provide: BaseApi, useClass: BaseApiStub }, // mocked class.
      ],
      schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();

  beforeEach(() => {
    fixture = TestBed.createComponent(EntityListComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});


在规范中编译组件时,预期行为是。它应该调用BaseApiStub,而不是调用BaseApi。我看到了以下解决方案。但是没有运气。
export class BaseApiStub extends BaseApi { }



无法进一步发展。有人可以纠正我的错误吗?

最佳答案

您尝试执行的操作无效。依赖注入(inject)和类继承没有直接关系。这意味着您不能像这样切换出服务的基类。

正如我所看到的,您有两种方法来做到这一点。

选项1:

除了模拟您的BaseApi并在测试中提供模拟之外,您还需要模拟EntityApi并在测试中提供该模拟。

选项2:

不必让EntityApi从BaseApi扩展,您可以使BaseApi成为简单服务并将其作为依赖项提供。

代替

class EntityApi extends BaseApi {
    constructor(private injector: Injector) {

你做
class EntityApi {
    constructor(private api: BaseApi) {

如果您这样设置EntityApi,则它不会从BaseApi扩展,而是将其作为依赖项。然后,您可以创建BaseApi的模拟并像在测试中一样提供它。

编辑

关于您的评论:



这不是真的。假设BaseApi具有您要使用的方法foo()。扩展基类时,用法可能如下所示:
class EntityApi extends BaseApi {
    constructor(private injector: Injector) {}
    exampleMethod() {
        this.foo();
    }
}

如果只有依赖项,您仍然可以像下面这样调用方法:
class EntityApi {
    constructor(private api: BaseApi) {}
    exampleMethod() {
        this.api.foo();
    }
}

您无需从BaseApi扩展即可调用其上的方法。

09-30 17:29