I have a method in nest js controller which takes two arguments looks like below :
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(MemberType.OWNER)
@Post('')
@UseInterceptors(
FilesInterceptor('images', 4, {
storage: fileStorageProductImage,
fileFilter: fileFilter,
limits: fileSizeLimit,
}),
)
@UseInterceptors(new MulterInterceptor('images'))
public async addProduct(
@Req()
req: Request,
@UploadedFiles() files: Express.Multer.File[],
) {
//code
//
}
And here is my unit test
describe('Unit testing path 1', () => {
const MemberServiceProvider = {
provide: MemberService,
useClass: MemberServiceStub,
};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ProductsController],
providers: [MemberServiceProvider],
}).compile();
controller = module.get<ProductsController>(ProductsController);
});
//
const result = controller.addProduct(..., ...);
});
I currently dont know what to pass into that addProduct method since i dont know how to mock request object and Express.Multer.File[]. Thanks in advance
For anyone who is still looking for the answer. I just figured it how to solve this. First thing first we need to define a method that can be used to read files from our local machine via stream.
const fileToBuffer = (filename) => {
const readStream = fs.createReadStream(filename);
const chunks = [];
return new Promise((resolve, reject) => {
// Handle any errors while reading
readStream.on('error', (err) => {
// handle error
// File could not be read
reject(err);
});
// Listen for data
readStream.on('data', (chunk) => {
chunks.push(chunk);
});
// File is done being read
readStream.on('close', () => {
// Create a buffer of the image from the stream
resolve(Buffer.concat(chunks));
});
});
};
Then, we call that method inside our unit test
const imageBuffer = (await fileToBuffer(
__dirname + 'path-to-file',
)) as Buffer;
In our controller, the uploaded files has Express.Multer.File[] types so we have to make variables that has the same type as above.
const imageFiles: Express.Multer.File[] = [];
const myReadableStreamBuffer = new streamBuffers.ReadableStreamBuffer({
frequency: 10, // in milliseconds.
chunkSize: 2048, // in bytes.
});
myReadableStreamBuffer.put(imageBuffer as Buffer);
imageFiles.push({
buffer: imageBuffer,
fieldname: 'fieldname-defined-in-@UseInterceptors-decorator',
originalname: 'original-filename',
encoding: '7bit',
mimetype: 'file-mimetyp',
destination: 'destination-path',
filename: 'file-name',
path: 'file-path',
size: 955578,
stream: myReadableStreamBuffer,
});
Finally, we can call our addProduct method with newly created imagesFiles variable as arguments.