nest: Unable to run tests because Nest can't resolve dependencies of a service
I’m submitting a…
[ ] Regression
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
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
// role.controller.spec.ts
import {Test} from '@nestjs/testing';
import {TestingModule} from '@nestjs/testing/testing-module';
import {RoleController} from './role.controller';
import {RoleService} from './role.service';
describe('Role controller', () => {
let controller: RoleController;
let service: RoleService;
beforeEach(async () => {
const mod: TestingModule = await Test
.createTestingModule({
components: [
RoleService
],
controllers: [
RoleController
]
})
.compile();
controller = mod.get<RoleController>(RoleController);
service = mod.get<RoleService>(RoleService);
});
it('should be true', () => {
expect(true).toBe(true);
});
});
// role.controller.ts
import {Controller} from '@nestjs/common';
import {RoleService} from './role.service';
@Controller('role')
export class RoleController {
constructor (
private readonly roleService: RoleService
) {}
...
}
// role.service.ts
import {InjectModel} from '@nestjs/mongoose';
import {PaginateModel} from 'mongoose';
import {IRole} from './role.interface';
import {RoleSchema} from './role.schema';
@Component()
export class RoleService {
constructor (
@InjectModel(RoleSchema) private readonly model: PaginateModel<IRole>
) {}
...
}
Environment
- Node version: 8.2.1
- Platform: Mac OS 10.13.2
├── @nestjs/common@4.5.9
├── @nestjs/core@4.5.9
├── @nestjs/mongoose@2.0.0
├── @nestjs/swagger@1.1.3
├── @nestjs/testing@4.5.5
├── @types/body-parser@1.16.8
├── @types/express@4.11.0
├── @types/jest@22.0.1
├── @types/mongoose@4.7.32
├── @types/mongoose-paginate@5.0.6
├── @types/morgan@1.7.35
├── @types/node@8.5.8
├── body-parser@1.18.2
├── class-transformer@0.1.8
├── class-validator@0.7.3
├── jest@22.0.6
├── mongoose@4.13.9
├── mongoose-paginate@5.0.3
├── morgan@1.9.0
├── nodemon@1.14.11
├── reflect-metadata@0.1.10
├── rxjs@5.5.6
├── ts-jest@22.0.1
├── ts-node@4.1.0
├── tslint@5.9.1
├── tslint-eslint-rules@4.1.1
├── tslint-microsoft-contrib@5.0.1
└── typescript@2.6.2
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 5
- Comments: 54 (10 by maintainers)
Links to this issue
Commits related to this issue
- fix: resolve repository dependency in test code Thanks to the following issue and comment! https://github.com/nestjs/nest/issues/363#issuecomment-359115921 Further ToDo: - Make more generic mock cla... — committed to takayukioda/nestjs-typeorm by takayukioda 5 years ago
- fix: resolve repository dependency in test code Thanks to the following issue and comment! https://github.com/nestjs/nest/issues/363#issuecomment-359115921 Further ToDo: - Make more generic mock cla... — committed to takayukioda/nestjs-typeorm by takayukioda 5 years ago
Hey guys!
I’ve read the testing part of the database documentation but I could not find any hint or best practice for creating the
mockRepositoryobject.I would like to write tests where I mock the database layer of the service (e.g.: the
adminRepositoryof theAuthService) by providing good ol’ POJOs as data source. Is this achievable with the current version of TypeORM / Nest?There is a related conversation in typeorm/typeorm#1267, but I couldn’t get closer to my desired functionality.
My AuthService looks like this:
The desired output would look like something like this:
I really look forward to hear some advices and tips about the pros/cons of this kind of testing strategy, my primary goal is to keep my unit tests as simple and as fast as I can. I really appreciate any help!
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
@InjectRepository:I had more or less the same issue this morning and solved it by injecting “DogsRepository” manually:
However, I would recommend extending Repository<Dog> with a custom repo Class (
class DogsRepository extends Repository<Dog>) and use it in useClass (useClass: DogsRepository, instead ofuseClass: Repository), in order to be able to test the type of values returned by the repository instance (if you need to).@kamilmysliwiec: does everything sound correct? Or am I mistaken somewhere? Shall I add it do the documentation?
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 )
Example
DatabaseModule
CatModule
ApplicationModule ( for “normal” execution )
cat.e2e-spec.ts
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
test/jest-e2e.json. I also added the globals object there:And voila, everything’s running. Hopefully that’ll work for the rest of us too.
How to Solve the Problem
@ebadia Hi. Please have a look at this. Give a token (name of the injected dependency) as
provide(here, I use the default one:<entityName>Repository(e.g."UserRepository"), and the class to use to instantiate this dependency inuseClass(here, you want to inject an instance of “Repository” for your UsersService).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.
Hey guys trying to write some tests for mongoose models as well, having no luck with this, im getting
TypeError: Object prototype may only be an Object or null: undefinedI’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
results in
TypeError: Object prototype may only be an Object or null: undefinedwhileresults in
Error: Nest can't resolve dependencies of the RoleService (?). Please verify whether [0] argument is available in the current context.This is explained in the new version of the documentation: https://docs.nestjs.com/v5/
Hi all, I have tried by following these steps:
But I still have an error:
Am I wrong?
@mogusbi Not sure if you got @fwoelffel’s solution to work yet; but I had to put the mock in
componentsinstead ofimportsto get things working properly. Something like the following:That is because the
MongooseModule.forFeature(...)needs to inject yourConnectionobject. You should either addMongooseModule.forRoot(...)to your imports or mock yourRoleSchema.EDIT: See @shane-melton’s response
I you want to mock the
RoleSchema(which is the best option), try :If you’re wondering why
provide: 'RoleSchemaModel'have a look at this 😉EDIT: Missing link
https://github.com/nestjs/mongoose/blob/master/lib/mongoose.utils.ts#L3
@mazyvan I ran into the same problem, here is what i found to work for me: My custom repository:
My Service constructor
and the spec file:
Notice that I get the
repositoryTokenforUserRepositoryinstead ofUserI’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
{ provides: getRepositoryToken(...), useWhatever }works nicely for simple modules. The problem is when your tested module imports any other module, that depends (maybe indirectly) on any other db providers. Then, you get an error, because the other modules importsTypeOrmModule.forFeature(...), which in turn “depends” onTypeOrmModule.forRoot:You can, of course, recursively list all the required imported providers in your call to
createTestingModule, and add all the mock db providers the same way, but it quickly becomes unmaintainable. A much simpler solution is to just import the whole tested module, and then use.overrideProviderfor each DB entity that the module uses (directly or not):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
TypeOrmModule), until I found out about.overrideProvider.The documentation is now moved to the root directory.
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-mongoose\dummy.controller.spec.ts ● Test suite failed to run
` and
`FAIL src\nest-provider\cats.controller.spec.ts ● Test suite failed to run
` I’ve played the whole day yesterday trying different options including suggestions from this thread: #438
The result is always the same 😦 What i am missing?
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?
Hi @VinceOPS ,
It still not working, I have tried both, by extending
Repository<Label>usingLabelRepositoryclass, and also by simply referringRepository.Where am I doing wrong? Here you can find the repository: https://github.com/samueleresca/Blog.NestGettingStarted
@kunal-relan In this case something like the following should work:
UserService
The spec file:
I’m not sure about the
useClass: Repositorypart, I would mock that out, but theprovidepart has to look like aboveExample: https://github.com/jkchao/blog-service/blob/nest/src/module/auth/__test__/auth.spec.ts
Does one has a idea to fix that? It can not be that there is no working sample to unit test a component or sample with this setup. I found multiple sample projects on GH but they all have no tests.
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?
Hi @samueleresca
The default injection token (for TypeORM repositories) is
<entityName>Repository. In your case,LabelRepository, notLabelsRepository.You can avoid typescript errors if you mention that your mock is partial:
@xavi-dev As it says, your mock definition is not complete. That’s why in the example there is
// @ts-ignoretelling the typescript compiler to ignore the missing properties error in your mock. Alternatively, you can either remove the type definition or define all 23 missing properties.This issue was referenced in a question on Stackoverflow. Here is my solution: https://stackoverflow.com/a/55366343/4694994
I think for me, I had two questions.
Solution: user.service.ts
user.service.spec.ts
Solution:
user.service.spec.ts
user.repository.ts
@ganchikov @ChenShihao @AlbertoNitro I have the same problem. Any idea??
@xxxtonixxx It’s not clear how you would inject it, I’ve tried the following
but it only yields this error;
Nest can't resolve dependencies of the useFactory (?). Please verify whether [0] argument is available in the current context.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