forked from nestjs/nest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
optional-factory-provider-dep.spec.ts
134 lines (128 loc) · 4.51 KB
/
optional-factory-provider-dep.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { Scope } from '@nestjs/common';
import { UnknownDependenciesException } from '@nestjs/core/errors/exceptions/unknown-dependencies.exception';
import { Test } from '@nestjs/testing';
import { expect } from 'chai';
describe('Optional factory provider deps', () => {
describe('when dependency is optional', () => {
describe('and it is available', () => {
it('then it should be injected into the factory function', async () => {
const defaultValue = 'DEFAULT_VALUE';
const moduleRef = await Test.createTestingModule({
providers: [
{
provide: 'FACTORY',
useFactory: dep => dep ?? defaultValue,
inject: [{ token: 'MISSING_DEP', optional: true }],
},
{ provide: 'MISSING_DEP', useValue: 'OPTIONAL_DEP_VALUE' },
],
}).compile();
const factoryProvider = moduleRef.get('FACTORY');
expect(factoryProvider).to.equal('OPTIONAL_DEP_VALUE');
});
});
describe('otherwise', () => {
it('"undefined" should be injected into the factory function', async () => {
const defaultValue = 'DEFAULT_VALUE';
const moduleRef = await Test.createTestingModule({
providers: [
{
provide: 'FACTORY',
useFactory: dep => dep ?? defaultValue,
inject: [{ token: 'MISSING_DEP', optional: true }],
},
],
}).compile();
const factoryProvider = moduleRef.get('FACTORY');
expect(factoryProvider).to.equal(defaultValue);
});
it('"undefined" should be injected into the factory function (scoped provider)', async () => {
const MY_PROVIDER = 'MY_PROVIDER';
const FIRST_OPTIONAL_DEPENDENCY = 'FIRST_OPTIONAL_DEPENDENCY';
const SECOND_OPTIONAL_DEPENDENCY = 'SECOND_OPTIONAL_DEPENDENCY';
const module = await Test.createTestingModule({
providers: [
{
provide: SECOND_OPTIONAL_DEPENDENCY,
useValue: 'second',
},
{
provide: MY_PROVIDER,
scope: Scope.REQUEST,
inject: [
{
token: FIRST_OPTIONAL_DEPENDENCY,
optional: true,
},
{
token: SECOND_OPTIONAL_DEPENDENCY,
optional: true,
},
],
useFactory: (first?: string, second?: string) => {
return { first, second };
},
},
],
}).compile();
expect(await module.resolve(MY_PROVIDER)).to.deep.equal({
first: undefined,
second: 'second',
});
});
});
});
describe('otherwise', () => {
describe('and dependency is not registered', () => {
it('should error out', async () => {
try {
const builder = Test.createTestingModule({
providers: [
{
provide: 'FACTORY',
useFactory: () => 'RETURNED_VALUE',
inject: ['MISSING_DEP'],
},
],
});
await builder.compile();
} catch (err) {
expect(err).to.be.instanceOf(UnknownDependenciesException);
}
});
});
});
describe('and dependency is registered but it cannot be instantiated', () => {
it('should error out', async () => {
try {
const builder = Test.createTestingModule({
providers: [
{
provide: 'POSSIBLY_MISSING_DEP',
useFactory: () => null,
inject: ['MISSING_DEP'],
},
{
provide: 'FACTORY',
useFactory: () => 'RETURNED_VALUE',
inject: [{ token: 'POSSIBLY_MISSING_DEP', optional: false }],
},
],
});
await builder.compile();
} catch (err) {
expect(err).to.be.instanceOf(UnknownDependenciesException);
expect(err.message).to
.equal(`Nest can't resolve dependencies of the POSSIBLY_MISSING_DEP (?). Please make sure that the argument MISSING_DEP at index [0] is available in the RootTestModule context.
Potential solutions:
- Is RootTestModule a valid NestJS module?
- If MISSING_DEP is a provider, is it part of the current RootTestModule?
- If MISSING_DEP is exported from a separate @Module, is that module imported within RootTestModule?
@Module({
imports: [ /* the Module containing MISSING_DEP */ ]
})
`);
}
});
});
});