Working with typescript project we are using s3 to save images.
The s3 operations aren't called directly from s3 but a service called FileService that has the basic structure to handle all the basic operations looks like this:
static getSignedUrlFromS3(info: SignedUrlInfo) {
try {
return s3.getSignedUrlPromise(info.operationType, {
Bucket: info.bucket,
Key: info.key,
Expires: info.expires,
});
} catch (error) {
winston.error(
`Error retrieving signed url '${info.key}' from S3 Bucket '${info.bucket}'`,
error,
);
return Promise.resolve();
}
}
/**
* Get a list of objects from a S3 bucket.
*/
static getBucketObjectsList(info: ObjectListInfo) {
try {
return s3
.listObjectsV2({
Bucket: info.bucket,
Delimiter: info.delimiter,
Prefix: info.prefix,
})
.promise();
} catch (error) {
winston.error(
`Error retrieving object list from S3 Bucket '${info.bucket}'`,
error,
);
return Promise.resolve();
}
/**
* Creates a S3 Presigned Post that for add an object into S3 bucket
*/
static createS3PresignedPost(info: PresignedUrlInfo) {
try {
const params = {
Bucket: info.bucket,
Fields: {
key: info.key,
},
Expires: info.expires,
};
return s3.createPresignedPost(params);
} catch (error) {
winston.error(
`Error creating presigned POST for S3 Bucket '${info.bucket}'`,
error,
);
return;
}
}
So basically I have another Service that consumes this one calling the specific methods of the other service as follow:
static getOne(key: string): Promise<Response> {
return new Promise(async (resolve, reject) => {
const signedUrl = await FileService.getSignedUrlFromS3({
bucket: bucketName,
operationType: 'getObject',
key: key,
expires: 60 * 60 * 24,
});
if (typeof signedUrl === 'string') {
resolve({
key,
url: signedUrl,
date: this._getDateFromKey(key),
});
} else {
winston.error(`Error finding ${bucketName}/${key} in S3`);
reject(new ServerExceptionBadRequest('Unable to get media file.'));
}
});
}
So my question is how can I mock S3 to simulate the functionality of the services like make a signedPost GetObject, CopyObject etc.
What I have seen in documentation about is something like this:
jest.mock('@aws-sdk/client-s3');
import { VehicleMediaService } from '@api-services/VehicleMediaService';
import {
MediaStatus,
MediaType,
} from '@api-services/VehicleMediaService.interfaces';
import * as S3 from '@aws-sdk/client-s3/S3.spec';
const mocked = S3 as jest.Mocked<typeof S3>;
But not quite super sure about how to used. Thank you very much for your help.
The solution is mock the services using the aws-sdk. For example:
jest.spyOn(yourService, 'yourMethod').mockImplementation(() => {
const response = new Response<S3.Types.ListObjectsV2Output, AWSError>();
const result: PromiseResult<S3.Types.ListObjectsV2Output, AWSError> = {
$response: response,
Contents: objectFiles,
};
return Promise.resolve(result);
});
So that way you can mock any aws service.