i am writing unit test on one of my service. I am keep getting Error: Can't resolve all parameters for StateObservable: (?). and my test is failing.
can anyone tell me what is the issue?
spec file code
fdescribe("Physician Service", () => {
let physicianService: PhysicianService;
let httpTestingController: HttpTestingController;
let backend: MockBackend;
let initialResponse: any;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
],
providers: [
Http,
ConnectionBackend,
UtilService,
StateObservable,
RouterModule,
SessionService,
HttpClientTestingModule,
BaseRequestOptions,
MockBackend,
PhysicianService,
AuthService,
BrowserXhr,
XHRBackend,
Store,
{
deps: [
MockBackend,
BaseRequestOptions
],
provide: Http,
useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
}
}
],
schemas:[
NO_ERRORS_SCHEMA
]
});
});
fit("Should Create Physicians Service",
inject([PhysicianService], (physicianService: PhysicianService) => {
expect(physicianService).toBeTruthy();
}));
});
can anyone help me in this regard
Thanks
This should have an actual answer instead of being in the comments.
In the TestBed.configureTestingModule imports add StoreModule.forRoot({})
TestBed.configureTestingModule({
imports: [
...
StoreModule.forRoot({})
],
providers: [
...
]
});
Related
I have the following error :
Nest can't resolve dependencies of the ParametrageRepository (?). Please make sure that the argument DataSource at index [0] is available in the TypeOrmModule context.
My test code :
describe("ParametrageController (e2e)", () => {
let parametrage: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [ParametrageModule],
}).compile();
parametrage = moduleFixture.createNestApplication();
await parametrage.init();
});
it("/ (POST)", () =>
request(parametrage.getHttpServer())
.post("/parametrage")
.send({
libelle: "GROUPE_TYPE",
liste: ["TEAM", "SERVICE", "ORGANISATION"],
})
.expect(201));
});
My module code:
#Module({
imports: [TypeOrmModule.forFeature([Parametrage])],
exports: [TypeOrmModule],
controllers: [ParametrageController],
providers: [ParametrageService, ParametrageRepository, ParametrageActions, Logger],
})
export class ParametrageModule {}
I cannot tel why I have this error since I followed the Nestjs documentation. Maybe I skipped a part I don't know. Maybe it's because of my providers that has parameters in their constructors :
My ParametrageRepository provider :
#Injectable()
export class ParametrageRepository
extends RepositoryStarter<Parametrage, IParametrageListFilter>
implements IParametrageRepository
{
constructor(#InjectDataSource() datasource: DataSource) {
super(datasource.getRepository(Parametrage));
}
I tried to add providers injection :
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [ParametrageModule],
** providers: [
{ provide: ParametrageActions, useValue: ParametrageActions },
{ provide: ParametrageRepository, useValue: ParametrageRepository },
{ provide: Logger, useValue: Logger ,
],**
}).compile();
But stil the same error, it didn't solved anything
Thanks in advance
I want to use the CacheModule in the AuthModule and I have written this code but still getting the error in the console:
The Auth.module.ts file in which I want to import the cache module:
#Module({
providers: [CacheConfigService, SupertokensService],
exports: [],
imports: [CacheConfigModule, UsersModule],
controllers: [],
})
export class AuthModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(AuthMiddleware).forRoutes('*');
}
static forRoot({
connectionURI,
apiKey,
appInfo,
}: AuthModuleConfig): DynamicModule {
return {
// providers and exports
imports: [CacheConfigModule],
};
}
}
The cache config.module.ts file code. The cache config.service.ts file contains the logic:
#Module({
providers: [CacheConfigService],
exports: [CacheConfigService],
imports: [
CacheModule.register<RedisClientOptions>({
isGlobal: true,
// store: redisStore,
url: 'redis://' + process.env.REDIS_HOST + ':' + process.env.REDIS_PORT,
}),
],
})
export class CacheConfigModule {}
I want to use the cache service in the following class:
#Injectable()
export class SupertokensService {
private redisClient = redis.createClient({
url: this.cacheConfigService.url,
});
constructor(
#Inject(forwardRef(() => UsersService)) private userService: UsersService,
private cacheConfigService: CacheConfigService
) {
supertokens.init({
appInfo: this.config.appInfo,
supertokens: {
connectionURI: this.config.connectionURI,
apiKey: this.config.apiKey,
},
recipeList: [
ThirdPartyEmailPassword.init({
providers: [
ThirdPartyEmailPassword.Google({
clientSecret: 'TODO: GOOGLE_CLIENT_SECRET',
clientId:
'CLIENT_ID',
}),
],
signUpFeature: {
...signup logic
},
override: {
apis: (originalImplementation: any) => {
return {
...originalImplementation,
emailPasswordSignInPOST: async (input: any) => {
if (
originalImplementation.emailPasswordSignInPOST === undefined
) {
throw Error('Should never come here');
}
let response: any =
await originalImplementation.emailPasswordSignInPOST(input);
// retrieving the input from body logic
const { email } = inputObject;
const user = await this.userService.findOneByEmail(email);
const id = user?.id;
const token = jwt.sign({email, id}, 'mysecret';, {
expiresIn: '2h',
});
response.token = token;
await this.redisClient.set("Token", token, {
EX: 60 * 60 * 24,
});
return response;
},
};
},
},
}),
],
});
}
}
The error has been thrown because you have used ConfigService in CacheConfigService, but it has never been imported into CacheConfigModule.
If you want to have ConfigService then you must import it into AppModule, as well as CacheConfigModule.
app.module.ts:
import { ConfigModule } from '#nestjs/config';
import configuration from './config/configuration'; // or wherever your config file exists
#Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
}),
// rest of code
],
// rest of code
})
export class AppModule {}
config.module.ts:
import { ConfigModule } from '#nestjs/config';
#Module({
providers: [CacheConfigService],
exports: [CacheConfigService],
imports: [
CacheModule.register<RedisClientOptions>({
isGlobal: true,
// store: redisStore,
url: 'redis://' + process.env.REDIS_HOST + ':' + process.env.REDIS_PORT,
}),
ConfigModule,
],
})
export class CacheConfigModule {}
I am developing a module that suppport forRoot and forChild. Whenever this module is imported with forRoot, forChild some methods of a custom service should be called. It works well for forRoot since I use APP_INITIALIZER, but the factory is not called anymore in the forChild of a lazy loaded module. How can I execute the methods that I have in my factory in the forChild so that it also works with lazy loaded modules? Is there some sort of equivelant of the APP_INITIALIZER for lazy loaded modules or a workaround?
export const TRANSLATION_CONFIGURATION = new InjectionToken<TranslationConfiguration<any>>('');
function initializeAppFactory(config: TranslationConfiguration<any> & { language: Language }, locutus: LocutusService): () => void {
return () => {
if (config.language) {
locutus.registerRoot(config);
return;
}
locutus.registerChild({
scope: config.scope,
loaders: config.loaders
});
};
}
#NgModule({
declarations: [
NgxLocutusComponent,
LocutusDirective,
LocutussPipe
],
imports: [
CommonModule
],
exports: [
NgxLocutusComponent,
LocutusDirective,
LocutussPipe
]
})
export class LocutusModule {
static forRoot<T>(config: TranslationConfiguration<T> & { language: Language }): ModuleWithProviders<LocutusModule> {
return {
ngModule: LocutusModule,
providers: [
{
provide: TRANSLATION_CONFIGURATION,
useValue: config,
},
{
provide: APP_INITIALIZER,
useFactory: initializeAppFactory,
deps: [
TRANSLATION_CONFIGURATION,
LocutusService
],
multi: true
},
]
};
}
static forChild<T>(config: TranslationConfiguration<T>): ModuleWithProviders<LocutusModule> {
return {
ngModule: LocutusModule,
providers: [
{
provide: TRANSLATION_CONFIGURATION,
useValue: config,
},
{
provide: APP_INITIALIZER,
useFactory: initializeAppFactory,
deps: [
TRANSLATION_CONFIGURATION,
LocutusService
],
multi: true
},
]
};
}
}
I have some service in which I inject the CACHE_MANAGER in the constructor
import { CACHE_MANAGER, Inject, Injectable } from '#nestjs/common';
import { Cache } from 'cache-manager';
...
export class ManagerService {
constructor(#Inject(CACHE_MANAGER) private cacheManager: Cache) {}
...
}
That gives me an error when I test the modules the import those service
Nest can't resolve dependencies of the ManagerService (?). Please make sure that the argument CACHE_MANAGER at index [0] is available in the Web3ManagerService context.
I'm relatively new to NestJs so I really cannot figure out how to solve it
To inject the cache manager provider under the CACHE_MANAGER, you need to import the nestjs module that creates this provider into the module that has the ManagerService
#Module({
imports: [CacheModule.register()], // <<<<
providers: [ManagerService],
})
export class AppModule {}
like the docs shows https://docs.nestjs.com/techniques/caching
I just had the same problem and resolved it this way:
manager.service.spec.ts
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ManagerService, { provide: CACHE_MANAGER, useValue: {} }],
}).compile();
service = module.get<ManagerService>(ManagerService);
});
Set isGlobal: true:
CacheModule.register({
url: process.env.REDIS_URL,
db: 0,
port: parseInt(process.env.REDIS_PORT),
password: process.env.REDIS_PASSWORD,
isGlobal: true, //<<<<<<<
})
I have a Angular service that looks something like this:
import {environment} from '../environment'
....
public something() {
if(environment.production)
{
// do stuf
} else {
// do something else
}
}
Now i want to test both cases (dev and prod environemnt). How do I "mock" when the environment is imported ?
So i came up with a solution where I didn't have to check for the environment in my service:
I used the useFactory:
NgModule({
declarations: [],
imports: [],
providers: [
{
provide: Service,
useFactory: (httpClient: HttpClient) => {
if (environment.production) {
return new MyCustomService(httpClient);
} else {
return new Service();
}
},
deps: [HttpClient],
}
],
bootstrap: [AppComponent]
})
This way i manage which service is provided when the application is started up