沿库导出服务存根时的循环依赖

Circular dependency when exporting a service stub along library

我已经将与 websocket 接口的交互抽象到它自己的库中。这个库提供了一个单例服务来实现应用程序。

我现在正在尝试测试依赖于此库的组件。这是简化版和工作版:

imports (...)

class MessageServiceStub {
  private testData: WebsocketMessage =
  {
    'raw': new MessageEvent('type'),
    .....
  };
  public getMessageStream = (): any => {
    return Observable.of(this.testData);
  }
  public getStateStream = (): any => {
    return Observable.of(this.testData);
  }
}

describe('LandingComponent', () => {
  let component: LandingComponent;
  let fixture: ComponentFixture<LandingComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [LandingComponent],
      imports: [ClarityModule.forRoot(), ReactiveFormsModule]

    }).overrideComponent(LandingComponent, {
      set: {
        providers: [
          { provide: MessageService, useClass: MessageServiceStub },
        ]
      }
    }).compileComponents();
  }));

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

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

为了概括测试文件并专注于小型独立测试,该库还导出了 MessageServiceStub。但是,从 .spec 中删除 MessageServiceStub 并从库中导入它会导致以下错误:

Error: Invalid provider for MessageService. useClass cannot be undefined.
           Usually it happens when:
           1. There's a circular dependency (might be caused by using index.ts (barrel) files).
           2. Class was used before it was declared. Use forwardRef in this case.

我研究了多种可能的解决方案(包括 forwardRef'ing MessageServiceStub),但没有成功。虽然错误消息看起来很明显,但其解决方案却并非如此。

原来这个问题可以通过从其各自的文件显式导入存根来规避:

使用

import { MessageService, WebsocketMessage } from 'messageLib/ng-websocket';
import { MessageServiceStub } from 'messageLib/lib/stubs/messageServiceStub';

而不是

import { MessageService, WebsocketMessage, MessageServiceStub } from 'messageLib/ng-websocket';