I'm very new to unit testing and very excited about it. But I've uncertainty whether I should add defensive programming style or not to my production code. So, please see the following codes.
calclateFinalYearGPA.js (production code)
const _ = require('lodash'); const getGPAPoint = require('./getGPAPoint'); module.exports = function (gradings) { let totalPoint = 0; gradings.forEach((grading) => { const grade = grading.grading.grade.name; const point = getGPAPoint(grade); totalPoint += point; }); const finalYearGPA = _.round(totalPoint / gradings.length, 1); return finalYearGPA; }; The gradings is an array of objects which is pulled from the db, with the following structure.
"gradings": [ { "grading": { "gradeId": 3, "grade": { "gradeId": 3, "name": "A-" } } }, ... ] In my calculateFinalYearGPA.js, I loop through that array and extract grading.grade.name which is A- in the above structure, and pass it to getGPAPoint. It will return the decimal number.
So, now in my calculateFinalYearGPA.test.js test, I've add the following code which is test whether it fails when gradings is not an array.
const calculateFinalYearGPA = require('../../../utils/calculateFinalYearGPA'); describe('calculateFinalYearGPA', () => { it('should throw an exception if input is not an array', () => { const inputs = [1, 'a', null, undefined, {}]; inputs.forEach((i) => { expect(() => { calculateFinalYearGPA(i); }).toThrow(); }); }); }); So, now I need to add some defensive programming code to my production code.
if (gradings.constructor !== Array) throw new Error(`Expected to get an array, got ${typeof gradings}.`); The way I'm doing is correct? Should I test the gradings array has the proper structure as well? If so, I need to add some code that nothing with business logic is done but check the gradings array's structure. My production code will populate with that kind of code. Is it supposed to be?
What is the proper ways to test my calculateFinalYearGPA.js?
gradings.lengthis 0, which currently throws an error where you might want to return 0. It's the kind of scenarios where it's useful to explicitely capture behaviour for edge cases.gradingsarray structure? Do I need to add some checking in production code and test it in my test as well?