I have a function being returned inside an object that I'm trying to have test coverage for. I'm using vanilla JavaScript and Jest.
Here's my code...
function getDataManager() {
const config = conf(env);
const { data } = config;
if (process.env.NODE_ENV === 'test') {
return createStub(data);
}
return new DataManager();
}
function createStub(data) {
const smtpData = {
user: data.smtp.user,
pass: data.smtp.pass,
};
const dataManager = {
// this function is here to mimic the real dataManager
getSecretData(name) {
if (name === 'internalString') {
return smtpData;
}
throw new Error('Unable to retrieve data.');
},
};
return dataManager;
}
The part I don't have test coverage for yet is this function inside of the dataManager object...
getSecretData(name) {
if (name === 'internalString') {
return smtpData;
}
throw new Error('Unable to retrieve data.');
}
The code does work though... All of my other tests are still passing, meaning they got and used the stub. When I deploy the Postman tests are passing as well, meaning the real dataManager was used.
I found an open issue (https://github.com/facebook/jest/issues/8709) that seems similar to what I'm trying to do, but I'm hoping someone has been able to get it to work... or also please comment if you have suggestions for a different way to send the stub.
The reason for this stub existing is because I didn't find a way to successfully test with a local version of AWS Secrets Manager. I'm using nodejs serverless-offline to test the other services. If anybody else had success working with SecretsManager locally, that would be helpful to me too. :)
I was probably making this harder than it needed to be... Here's the test I ended up with. I had to export the function that creates the stub though to call it directly though. I'm not crazy about doing that, but it did get the test to work and was sufficient for the code coverage tool...
Here's the test:
describe('createSecretsManagerSub()', ()=>{
describe('stub returns an object with getSecretData()', () => {
it('and returns the username and password that is expected from Secrets Manager', () => {
const mockSecretName = 'internalString';
const mockData = {
smtp: {
UserName: "testUsername",
Password: "testPassword"
}
};
const stubbedSM = createSecretsManagerStub(mockData);
const stubObjData = stubbedSM.getSecretData(mockSecretName);
const expected = {
UserName: mockData.smtp.UserName,
Password: mockData.smtp.Password
};
expect(stubObjData).toEqual(expected);
});
});
});
Here's the function:
export function createSecretsManagerStub(data) {
logger.logInfo('factory.createSecretsManagerStub()');
const smtpData = {
UserName: data.smtp.UserName,
Password: data.smtp.Password,
};
const dataManager = {
getSecretData(name) {
logger.logInfo('Secrets Manager STUB: getSecretData()');
logger.logInfo(`Name passed in was: ${name}`);
return smtpData;
},
};
return dataManager;
}
Still feel free to comment if you want, I'm still learning and greatly appreciate any feedback.