I am try trying to implement unit test code for my nestjs application but I keep getting this error.
A circular dependency has been detected inside RootTestModule. Please, make sure that each side of a bidirectional relationships are decorated with "forwardRef()".
I checked my service and controller file but could not find any issue with it.
Service file
import { Injectable, NotFoundException } from '@nestjs/common';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { Grocery, GroceryDocument } from './schemas/grocery-list.schema';
@Injectable()
export class GroceryService {
constructor(
@InjectModel('GroceryService')
private readonly groceryModel: Model<GroceryDocument>,
) {}
// Create new Grocery Record
async create(
item: string,
category: string,
quantity: number,
): Promise<Grocery> {
const newGrocery = new this.groceryModel({
// userId: uuidv4(),
item,
category,
quantity,
});
const result = await newGrocery.save();
return new Grocery(result.item, result.category, result.quantity);
// return await this.groceryModel.create({
// userId: uuidv4(),
// item,
// category,
// quantity,
// });
// return newGrocery.save();
}
// Read all Grocery Records
async readAll(): Promise<Grocery[]> {
const groceryList: Grocery[] = await this.groceryModel.find().exec();
if (!groceryList) {
throw new NotFoundException('No records found!');
}
return groceryList;
}
async readById(id): Promise<Grocery> {
try {
const specifiedGrocery = await this.groceryModel.findById(id).exec();
return specifiedGrocery;
} catch (err) {
throw new NotFoundException('Invalid ID provided');
}
}
async update(id, grocery: Grocery): Promise<Grocery> {
try {
const specifiedGrocery = await this.groceryModel.findByIdAndUpdate(
id,
grocery,
{
new: true,
},
);
return specifiedGrocery;
} catch (err) {
throw new NotFoundException('Invalid ID provided');
}
}
async delete(id): Promise<any> {
try {
const specifiedGrocery = await this.groceryModel.findByIdAndRemove(id);
if (!specifiedGrocery) {
throw new NotFoundException('Grocery with given ID does not exist');
}
// return specifiedGrocery;
} catch (err) {
throw new NotFoundException('Invalid ID provided');
}
}
}
Controller file
import {
Body,
Controller,
Delete,
Get,
HttpStatus,
NotFoundException,
Param,
Post,
Put,
Res,
} from '@nestjs/common';
import {
ApiBadRequestResponse,
ApiBody,
ApiCreatedResponse,
ApiOkResponse,
ApiOperation,
ApiParam,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { GroceryService } from './grocery-list.service';
// import { Grocery } from './schemas/grocery-list.schema';
import { UpdateGroceryDto } from './dto/update-grocery.dto';
import { CreateGroceryDto } from './dto/create-grocery.dto';
@ApiTags('grocery-list')
@Controller('grocery-list')
export class GroceryListController {
constructor(private readonly groceryService: GroceryService) {}
// GET all groceries
@Get()
@ApiOperation({ summary: 'Get all the data from this api' })
@ApiOkResponse({
status: 200,
description: `List of Groceries`,
type: [CreateGroceryDto],
})
@ApiResponse({
status: 500,
description: `Internal Server Error`,
})
@ApiBadRequestResponse()
async fetchAll(@Res() response) {
const groceries = await this.groceryService.readAll();
return response.status(HttpStatus.OK).json({
groceries,
});
}
// GET a specific grocery
@Get('/:id')
@ApiOperation({
summary: 'Get a particular data with given ID from this api',
})
@ApiParam({
name: 'id',
type: 'string',
description: 'enter unique id',
required: true,
})
@ApiOkResponse({
status: 200,
description: `Get a unique ID from the groceries list`,
type: CreateGroceryDto,
})
@ApiResponse({
status: 500,
description: `Internal Server Error`,
})
@ApiBadRequestResponse()
async findById(@Res() response, @Param('id') id) {
const grocery = await this.groceryService.readById(id);
return response.status(HttpStatus.OK).json({
grocery,
});
}
// POST operation
@Post()
@ApiOperation({ summary: `create new record` })
@ApiCreatedResponse({
status: 201,
description: `Added new grocery record`,
type: CreateGroceryDto,
})
@ApiResponse({
status: 500,
description: `Internal Server Error`,
})
@ApiBadRequestResponse()
async createGrocery(@Res() response, @Body() grocery: CreateGroceryDto) {
const newGrocery = await this.groceryService.create(
grocery.item,
grocery.category,
grocery.quantity,
);
console.log(newGrocery);
return response.status(HttpStatus.CREATED).json({
newGrocery,
});
}
// PUT operation
@Put('/:id')
@ApiOperation({ summary: 'Update a single Id from this api' })
@ApiParam({
name: 'id',
type: 'string',
description: 'enter unique id',
required: true,
})
@ApiCreatedResponse({
status: 201,
description: `Updated existing grocery record`,
type: CreateGroceryDto,
})
@ApiResponse({
status: 403,
description: `Forbidden`,
})
@ApiResponse({
status: 500,
description: `Internal Server Error`,
})
@ApiBadRequestResponse()
async update(
@Res() response,
@Param('id') id,
@Body() grocery: CreateGroceryDto,
) {
const updatedGrocery = await this.groceryService.update(id, grocery);
if (!updatedGrocery) {
throw new NotFoundException('id not found');
}
return response.status(HttpStatus.OK).json({
updatedGrocery,
});
}
// DELETE operation
@Delete('/:id')
@ApiOperation({ summary: 'Delete a single Id from this api' })
@ApiParam({
name: 'id',
type: 'string',
description: 'enter unique id',
required: true,
})
@ApiOkResponse({
status: 200,
description: `Delete a grocery record with provided ID`,
type: UpdateGroceryDto,
})
@ApiResponse({
status: 403,
description: `Forbidden`,
})
@ApiResponse({
status: 500,
description: `Internal Server Error`,
})
@ApiBadRequestResponse()
async delete(@Res() response, @Param('id') id) {
const deletedGrocery = await this.groceryService.delete(id);
return response.status(HttpStatus.OK).json({
deletedGrocery,
});
}
}
Module file
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { GroceryListController } from './grocery-list.controller';
import { GroceryModel } from './schemas/grocery-list.schema';
import { GroceryService } from './grocery-list.service';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'GroceryService', schema: GroceryModel }]),
],
controllers: [GroceryListController],
providers: [GroceryService],
})
export class GroceryListModule {}