-
-
Notifications
You must be signed in to change notification settings - Fork 7.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to run tests because Nest can't resolve dependencies of a service #363
Comments
I suppose it's failing because in your RoleService you are injecting an mongoose model, which is not including in the testing module. You should create a mock or inject the real one |
@xxxTonixxx It's not clear how you would inject it, I've tried the following beforeEach(async () => {
const mod: TestingModule = await Test
.createTestingModule({
components: [
RoleService
],
controllers: [
RoleController
],
imports: [
MongooseModule.forFeature([
{
name: 'Role',
schema: RoleSchema
}
])
]
})
.compile();
controller = mod.get<RoleController>(RoleController);
service = mod.get<RoleService>(RoleService);
}); but it only yields this error; |
That is because the EDIT: See @shane-melton's response I you want to mock the beforeEach(async () => {
const mod: TestingModule = await Test
.createTestingModule({
components: [
RoleService
],
controllers: [
RoleController
],
imports: [
{
provide: 'RoleSchemaModel',
useValue: {
// Your mock
}
}
]
})
.compile();
controller = mod.get<RoleController>(RoleController);
service = mod.get<RoleService>(RoleService);
}); If you're wondering why EDIT: Missing link |
@fwoelffel look at what? My apologies if this appears to be a bit of stupid question but what would a mocked schema look like Once I can get this working I'll put in a pull request to include a test in the mongoose module example |
The only stupid thing here is me forgetting to c/c the link... Here it is https://github.com/nestjs/mongoose/blob/master/lib/mongoose.utils.ts#L3 According to your code, and my understanding (I've never used Mongoose), your mock should look like a |
Hi, |
@mogusbi Not sure if you got @fwoelffel's solution to work yet; but I had to put the mock in beforeEach(async () => {
const mod: TestingModule = await Test
.createTestingModule({
components: [
RoleService,
{
provide: 'RoleSchemaModel',
useValue: {
// Your mock
}
}
],
controllers: [
RoleController
],
}
]
})
.compile();
controller = mod.get<RoleController>(RoleController);
service = mod.get<RoleService>(RoleService);
}); |
For people encoutering the same error message with TypeORM, please note that the DI loader cannot "know" your Repository instances as they're injected with
I had more or less the same issue this morning and solved it by injecting "DogsRepository" manually:
However, I would recommend extending Repository with a custom repo Class ( @kamilmysliwiec: does everything sound correct? Or am I mistaken somewhere? Shall I add it do the documentation? |
I'm having no luck at all with this, I still can't work out how to mock the schema and even using the actual schema results in an error regardless of whether it's included in components or imports const mod: TestingModule = await Test
.createTestingModule({
components: [
RoleService
],
controllers: [
RolesController
],
imports: [
{
provide: 'RoleSchemaModel',
useValue: RoleSchema
}
]
})
.compile(); results in const mod: TestingModule = await Test
.createTestingModule({
components: [
RoleService,
{
provide: 'RoleSchemaModel',
useValue: RoleSchema
}
],
controllers: [
RolesController
]
})
.compile(); results in |
@VinceOPS I'm having this issue with TypoORM, but cannot see what exactly I shall do. I have my UsersService with this code: @Component()
export class UsersService {
constructor(
@InjectRepository(User)
private readonly usersRepo: Repository<User>
) {}
//... I written this in the spec file for the test: //...
beforeEach( async () => {
const module = await Test.createTestingModule({
components: [ UsersService, {
provide: User,
useClass: Repository
} ],
controllers: [ UsersController ],
}).compile()
//... But I have no clear what I need to write in
|
@ebadia Hi. Please have a look at this. |
Hi all,
But I still have an error:
Am I wrong? |
The default injection token (for TypeORM repositories) is |
Hi @VinceOPS , It still not working, I have tried both, by extending Where am I doing wrong? Here you can find the repository: |
Hey! I have almost the same situation as @samueleresca but with mongoose models. Neither registering a mock as component nor importing it resolves it. Since almost every class to test somehow depends on a mongoose model I cannot write any tests. After reading through this issue I can't provide anything new. I made sure to update all dependencies to the latest version (4.6.4 in case of nestjs). So does anyone has a working example? |
Hey guys trying to write some tests for mongoose models as well, having no luck with this, im getting |
i have a same problem |
same here.. using... Nest can't resolve dependencies of the DemoService (?). Please verify whether [0] argument is available in the current context. |
Is there any way at all to make this error message more helpful? Listing what has been included would be really good. I've been able to get to the bottom of it sometimes, but I've also just had to roll back my code and do something else. Also he was asking about database testing, can we get an example that doesn't use mocks? |
In the documentation "Mongoose.forRoot" is imported in the Application module, this module is not imported during the creation the TestModule leading to this error as Mongoose.forFeature won't be able to find the connection initialized by Mongoose.forRoot. You can declare "Mongoose.forRoot()" in your Test.createTestModule() statement or use a similar as me : ( please note that i have multiple database in my real project thats why i have a DatabaseModule ) ExampleDatabaseModule
CatModule
ApplicationModule ( for "normal" execution )
cat.e2e-spec.ts
|
Can someone help me to understand the issue? i've created an example of simple app with 2 modules (dummy using nest/mongoose and cats using custom provider as per the doc: https://github.com/ganchikov/nest_mongo_ut_sample Both modules have tests:
the app itself is successfully executed, but when I run the test I get the following error for both modules:
` `FAIL src\nest-provider\cats.controller.spec.ts
` The result is always the same :( What i am missing? |
@ganchikov also i have the same problem exactly... Any solution please ? |
This is how I fixed it in my case: So this is what I did (I'm using mocha but it should be the same with jest):
And in testDatabse file :
Works fine so far and it's kind of amazing that it can access the database only using a portion of the entities that the db has! So basically recreate the exact module in the test (Without importing the module itself) but before this add the connection to your desired database first. I used this simple functional wrapper to do that, you can do it your own way. I like this approach even if it has a bit more work because it lets you see what entities are connected with the entity you're testing just by looking at the test's imports. I hope this works with mongodb too. |
@ganchikov +1. Waiting for solution... |
This is explained in the new version of the documentation: https://docs.nestjs.com/v5/
|
@ganchikov @ChenShihao @AlbertoNitro I have the same problem. Any idea?? |
Does one has a idea to fix that? |
I think you've run into the same issue as me. In order to use jest for testing, nest uses ts-jest to compile test files. Somehow ts-jest doesn't seem to handle synthetic default imports properly. As soon as I turned it off all tests passed. I've created a separate tsconfig for jest:
And configured ts-jest to use this in package.json:
Don't forget to also turn this off for e2e tests. By default, nest creates another configuration file for it under
And voila, everything's running. |
Do u have to implement findOne on your const mockRepository ?
|
Any update on this issue? |
I'll leave a note, since this issue comes up first in most google searches about mocks / unit tests with Typeorm in Nest. TL;DR see the example below, or the corrected link from @jkchao above: the https://github.com/jkchao/blog-service/blob/nest/src/module/auth/__test__/auth.service.spec.ts The recommended testing strategy (mentioned in the docs), to add
You can, of course, recursively list all the required imported providers in your call to const testingModule = await Test.createTestingModule({ imports: [YourTestedModule] })
.overrideProvider(getRepositoryToken(YourEntity1))
.useValue(...)
.overrideProvider(getRepositoryToken(YourEntity2))
.useValue(...)
.compile(); Maybe it's worth mentioning this approach in the "Techniques > Database > Testing" docs? It took me a surprisingly long time looking for other workarounds (including mocking the db connection itself inside |
@danil-z did you find an answer to this? |
@trainerbill if your function mockRepositoryProvider<T extends /*my base entity type*/>(entity: Type<T>): ValueProvider {
const mkFailFn = (name: string) => () => {
throw new Error(`unexpected/unmocked call to Repository<${entity.name}>.${name}`);
};
const mockRepo: Partial<Repository<T>> = [
'find',
'findOne',
'findOneOrFail',
'save',
'delete',
'remove',
].reduce(
(acc, fnName) => {
acc[fnName] = mkFailFn(fnName);
return acc;
},
{},
);
return {
provide: getRepositoryToken(entity),
useValue: mockRepo,
};
} Then, for each entity my test module needs, I do
|
@pterblgh pt
|
I spent a ton of time on finding a solution here so I am going to post what I came up with. Its a combination of @quezak solution and providing a mock value.
|
I think for me, I had two questions.
Solution:
user.service.spec.ts
Solution:
user.service.spec.ts
user.repository.ts
|
I can't make tests work using Having this in my service's constructor: constructor(
@InjectRepository(UserRepository)
private readonly userRepository: UserRepository,
) {} Tests does not work. But without the Here is a extract of the service's test beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
// imports: [TypeOrmModule.forFeature([User, UserRepository])],
providers: [
UserService,
{
provide: getRepositoryToken(User),
useValue: mockRepository,
},
],
}).compile();
service = module.get<UserService>(UserService);
}); And the test's output:
|
@mazyvan adding a custom provider directly in the module works only sometimes. To be sure it works, use the |
@mazyvan I ran into the same problem, here is what i found to work for me: @EntityRepository(User)
export class UserRepository extends Repository<User> {
public async findOneByEmail(email: string): Promise<User> {
return this.findOne({ where: { email } });
}
} My Service constructor export class LoginService {
constructor(
@InjectRepository(UserRepository)
private readonly userRepository: UserRepository,
) {}
// ...
} and the spec file: beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
LoginService,
{ provide: getRepositoryToken(UserRepository), useValue: mockRepository },
],
}).compile();
service = module.get<LoginService>(LoginService);
}); Notice that I get the |
Trying to use it for 3 days now. I'm getting error during creating testing Module:
Tryed a lot of variants but still the same error in injected file. With postman it all works good. So is there any fix for this? Error:
There is my project |
Thanks to the following issue and comment! nestjs/nest#363 (comment) Further ToDo: - Make more generic mock class to ease injections
Thanks to the following issue and comment! nestjs/nest#363 (comment) Further ToDo: - Make more generic mock class to ease injections
thanks for having this issue! One note that I needed to put mock into |
This issue was referenced in a question on Stackoverflow. Here is my solution: https://stackoverflow.com/a/55366343/4694994 |
@kiwikern I got this error with your code:
|
@Xavi-dev As it says, your mock definition is not complete. That's why in the example there is |
You can avoid typescript errors if you mention that your mock is partial:
|
Did you figure this out? if yes can you give an example in the same context. |
@kunal-relan UserService @Component()
export class UsersService {
constructor(
@InjectRepository(User)
private readonly usersRepo: Repository<User>
) {}
//... The spec file: import { getRepositoryToken } from '@nestjs/typeorm';
//...
beforeEach( async () => {
const module = await Test.createTestingModule({
components: [ UsersService, {
provide: getRepositoryToken(User),
useClass: Repository
} ],
controllers: [ UsersController ],
}).compile()
//... I'm not sure about the |
How to Solve the Problem |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
For those that are repeatedly struggling with the "Cannot resolve dependency" error, check out the NestJS Devtools (read more here). Example: |
I'm submitting a...
Current behavior
I have followed the unit test example but I am unable to get my very simple test to run (it's literally just testing if true === true) but it won't work because I'm met with this error
Nest can't resolve dependencies of the RoleService (?). Please verify whether [0] argument is available in the current context.
Minimal reproduction of the problem with instructions
You can find the repo at https://bitbucket.org/mogusbi/breeze-bb/
After cloning, run
npm run api:test
Environment
The text was updated successfully, but these errors were encountered: