【问题标题】:Storybook: Inject a mocked provider/service at component levelStorybook:在组件级别注入一个模拟的提供者/服务
【发布时间】:2021-02-23 00:22:31
【问题描述】:

我有一个具有组件级提供程序的 Angular 组件。

@Component({
  selector: 'storybook-di-component',
  templateUrl: './di.component.html',
  providers: [{ provide: TEST_TOKEN, useValue: 123 }],
})
export class DiComponent {
  @Input()
  title: string;

  constructor(
    protected injector: Injector,
    protected elRef: ElementRef,
    @Inject(TEST_TOKEN) protected testToken: number
  ) {}

在这种情况下,我如何让 storybook 注入不同的提供程序,以便我可以提供替代/模拟服务?比如上面的DiComponent,如果我想注入{ provide: TEST_TOKEN, useValue: 456 }呢?

现实世界的用例是我正在使用 ngrx/component-store 并且需要为组件提供一个虚拟的、预填充的存储。

(附加信息:) 在模块级别(如下所示)注入它不起作用,因为组件仍在运行并创建它自己的提供者实例:

moduleMetadata: {
        providers: [
            { provide: StateStore, useValue: stateStore }
        ],
        imports: [...],
    },

【问题讨论】:

    标签: angular ngrx storybook angular-storybook


    【解决方案1】:

    我最终使用低技术方法解决了这个问题。

    1. 子类化.stories.ts 文件中的组件
    2. 在子类中,声明构造函数以注入除需要模拟的服务之外的所有内容。
    3. 使用注入服务 + 模拟服务调用 super(...)

    鉴于我的实际需要是注入 ngrx/component-store 的模拟,我的 stories.ts 现在有如下内容:

    const stateStore = new RecordSuggestionsPageStore(mockSuggestionsService);
    stateStore.setState(() => ({
        selectableRecords: [
            { name: "John Legend", recordType: "employee" },
            { name: "Allan Davies", recordType: "employee" },
        ]
    }));
    
    @Component({
        selector: "myapp-suggested-records-page",
        templateUrl: "./suggested-records-page.component.html",
        styleUrls: ["./suggested-records-page.component.scss"]
    })
    class SuggestedRecordsPageComponentStubbed extends SuggestedRecordsPageComponent {
    
        constructor(router: Router) {
            super(stateStore, router);
        }
    }
    

    【讨论】:

      【解决方案2】:

      TypeProvider 适合我。对于您的示例,它类似于以下内容,其中 setState 的参数需要与被模拟的方法相匹配:

      class MockRecordSuggestionsPageStore implements Partial<RecordSuggestionsPageStore> {
        setState() {
          return [
            { name: "John Legend", recordType: "employee" },
            { name: "Allan Davies", recordType: "employee" },
          ]
        }
      }
      

      对于 SuggestedRecordsPageComponent 故事中的提供者

          moduleMetadata: {
            declarations: [...],
            imports: [...],
            providers: [
              { provide: StateStore, useClass: MockRecordSuggestionsPageStore }
            ],
          },
      

      【讨论】:

        猜你喜欢
        • 2019-07-16
        • 1970-01-01
        • 2020-07-14
        • 2019-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-18
        • 2019-04-04
        相关资源
        最近更新 更多