【问题标题】:How to provide an `InjectionToken` that has its own `factory`?如何提供具有自己的“工厂”的“InjectionToken”?
【发布时间】:2019-11-11 10:07:26
【问题描述】:

考虑以下InjectionToken 类型Foo

export const FOO = new InjectionToken<Foo>(
  'foo token',
  { factory: () => new Foo() });

现在假设我已经疯狂地瞄准了 100% 的测试覆盖率。为此,我必须对那个小 factory 函数进行单元测试。

我正在考虑创建一个在我的测试中只有一个提供程序的注入器:

const inj = Injector.create({
  providers: [{ provide: FOO }] // compiler error here
});

const foo = inj.get(FOO);

expect(foo).toBeTruthy();

不幸的是,这会因编译器错误而失败,因为没有 useValueuseFactoryuseExisting 属性的 { provide: FOO } 不是有效的提供程序。但是,当注入令牌带有自己的工厂时,为什么我不得不定义其中一个呢?

当然我尝试了所有选项:

  • useValue: FOO 编译运行,但是好像没有执行工厂方法
  • useFactory: () =&gt; FOO, deps: [] 也可以编译运行,但似乎也没有执行工厂方法
  • useExisting: FOO 编译,但在运行时失败并出现循环依赖错误

有趣的是,the documentation 中为 InjectionToken 提供了类似的场景,但它没有显示我正在寻找的注册:

const MY_SERVICE_TOKEN = new InjectionToken<MyService>('Manually constructed MyService', {
  providedIn: 'root',
  factory: () => new MyService(inject(MyDep)),
});

// How is `MY_SERVICE_TOKEN` token provided?

const instance = injector.get(MY_SERVICE_TOKEN);

我创建了一个example on StackBlitz,你可以自己试试。

【问题讨论】:

    标签: angular angular-dependency-injection


    【解决方案1】:

    当您为InjectionToken 指定factory 函数时,令牌会自动在root 中提供。因此,您也不需要在测试台中提供它。

    为了在测试中使用此功能,您需要使用TestBed 而不仅仅是Injector.create

    import { TestBed } from '@angular/core/testing';
    
    describe('Foo', () => {
      beforeEach(() => TestBed.configureTestingModule({}));
    
      it('should be created', () => {
        const service: Foo = TestBed.get(FOO);
        expect(service).toBeTruthy();
      });
    });
    

    The docs

    创建InjectionToken 时,您可以选择指定一个 返回(可能通过创建)默认值的工厂函数 参数化类型T。这设置了InjectionToken 使用 这个工厂作为提供者,就好像它在 应用程序的根注入器。如果工厂函数,它取零 参数,需要注入依赖项,它可以使用 inject 函数。请参阅下面的示例。

    【讨论】:

    • 感谢您的回答,但这不起作用。错误是StaticInjectorError[InjectionToken foo token]: NullInjectorError: No provider for InjectionToken foo token!。见这个例子:stackblitz.com/edit/angular-py8wbd(检查文件app.component.ts)。
    • @GoodNightNerdPride 更新了答案。您需要使用TestBed 而不是Injector
    猜你喜欢
    • 2019-04-18
    • 1970-01-01
    • 2021-09-08
    • 2018-05-22
    • 2018-10-19
    • 1970-01-01
    • 2019-01-29
    • 2021-12-18
    • 2018-09-01
    相关资源
    最近更新 更多