angular - 如何提供具有自己的“工厂”的“InjectionToken”?
问题描述
考虑以下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();
不幸的是,这会因编译器错误而失败,因为{ provide: FOO }
它不是没有 、 或 属性的有效useValue
提供useFactory
程序useExisting
。但是,当注入令牌带有自己的工厂时,为什么我不得不定义其中之一呢?
当然,我仍然尝试了所有选项:
useValue: FOO
编译并运行,但似乎没有执行工厂方法useFactory: () => FOO, deps: []
也编译和运行,但似乎也没有执行工厂方法useExisting: FOO
编译,但在运行时因循环依赖错误而失败
有趣的是,文档中提供了一个类似的场景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);
我在 StackBlitz 上创建了一个示例,您可以自己尝试一下。
解决方案
当您为 指定factory
函数时InjectionToken
,令牌会自动在 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();
});
});
文档说
创建 时
InjectionToken
,您可以选择指定一个工厂函数,该函数返回(可能通过创建)参数化类型的默认值T
。这设置了InjectionToken
使用这个工厂作为提供者,就好像它是在应用程序的根注入器中明确定义的一样。如果需要零参数的工厂函数需要注入依赖项,它可以使用该inject
函数来完成。请参阅下面的示例。
推荐阅读
- c# - Nhibernate返回带有列表的Json
- vue.js - 如何创建 Vue 可插拔组件
- android - 打字稿的 PayHere 沙箱实现
- excel - VBA 最佳实践 - 从另一个工作表格式化工作表
- javascript - 访问回调 array.prototype 中的参数
- file - 打印到标准输出使用 f95 写入打开的文件
- php - 教义 - 用户返回最近的日期
- jquery - 我们可以更改 Bower.json 中的 jQuery 包版本吗
- javascript - 我想在我的数据表中过滤掉那些相同的显示数据
- javascript - jQuery DataTable 行条件格式,按列总计