This rule:
Handle this exception or don’t catch it at all.
Exceptions should not be ignoredjavascript:S2486
should not be applied to unit tests by default. Ignoring errors in tests is a perfectly normal thing to do when you want your tests to be granular.
Consider the following function that generates a form validation error message:
export const VALIDATION_ERROR_MESSAGES = Object.freeze({
multilingual_unique: {
key: 'multilingual_unique',
messageFunction({ label, ruleParams }) {
const languageCodeString = ruleParams[0]
const languageCodeParsed = parseStringVariable(languageCodeString)
if (languageCodeParsed) {
const languageName = getLanguageName(languageCodeParsed)
return i18n.t('VALIDATION_ERROR_DEFAULT_MULTILINGUAL_UNIQUE', {
label,
languageName,
})
} else {
throw new Error(`No valid language code found when building error message for multilingual_unique, but the validation logic in multilingualUniqueRule flagged the field value as invalid. Check function logic.`)
}
},
},
})
See my tests for it:
import { VALIDATION_ERROR_MESSAGES } from '@/configurations/validationErrorMessages.js'
import * as parseStringVariableFile from '@/utils/environmentUtils/parseStringVariable.js'
import * as multilingualUtils from '@/utils/multilingualUtils.js'
describe(`validationErrorMessages.js`, () => {
describe(`VALIDATION_ERROR_MESSAGES`, () => {
describe(`multilingual_unique.messageFunction`, () => {
const LANGUAGE_CODE_PARSED = `language code (parsed)`
const LANGUAGE_NAME = `the name of the language`
let label
let languageCodeString
let ruleParams
let parseStringVariableSpy
let getLanguageNameSpy
beforeEach(() => {
label = `value for label`
languageCodeString = `value for languageCodeString`
ruleParams = [ languageCodeString ]
parseStringVariableSpy = jest.spyOn(parseStringVariableFile, 'parseStringVariable').mockReturnValue(LANGUAGE_CODE_PARSED)
getLanguageNameSpy = jest.spyOn(multilingualUtils, 'getLanguageName').mockReturnValue(LANGUAGE_NAME)
})
it(`SHOULD call parseStringVariable WITH languageCodeString (= ruleParams[0]).`, () => {
VALIDATION_ERROR_MESSAGES.multilingual_unique.messageFunction({
label,
ruleParams,
})
expect(parseStringVariableSpy).toHaveBeenCalledWith(languageCodeString)
})
it(`SHOULD call parseStringVariable WITH UNDEFINED IF ruleParams is an EMPTY array.`, () => {
ruleParams = []
VALIDATION_ERROR_MESSAGES.multilingual_unique.messageFunction({
label,
ruleParams,
})
expect(parseStringVariableSpy).toHaveBeenCalledWith(undefined)
})
describe(`languageCodeParsed (FROM parseStringVariable) is a NON-empty STRING`, () => {
it(`SHOULD call getLanguageName WITH languageCodeParsed.`, () => {
VALIDATION_ERROR_MESSAGES.multilingual_unique.messageFunction({
label,
ruleParams,
})
expect(getLanguageNameSpy).toHaveBeenCalledWith(LANGUAGE_CODE_PARSED)
})
it(`SHOULD return 'VALIDATION_ERROR_DEFAULT_MULTILINGUAL_UNIQUE' (translated WITH variables label (= arg) AND languageName (FROM getLanguageName)).`, () => {
const actual = VALIDATION_ERROR_MESSAGES.multilingual_unique.messageFunction({
label,
ruleParams,
})
expect(actual).toBe(`VALIDATION_ERROR_DEFAULT_MULTILINGUAL_UNIQUE_i18n_t_vars_label_${ label }_languageName_${ LANGUAGE_NAME }`)
})
})
describe(`languageCodeParsed (FROM parseStringVariable) is FALSY`, () => {
function testLanguageCodeParsedFalsy() {
it(`SHOULD NOT call getLanguageName.`, () => {
try {
VALIDATION_ERROR_MESSAGES.multilingual_unique.messageFunction({
label,
ruleParams,
})
} catch (error) {
// Ignore the error
}
expect(getLanguageNameSpy).not.toHaveBeenCalled()
})
it(`SHOULD throw.`, () => {
expect(() => {
VALIDATION_ERROR_MESSAGES.multilingual_unique.messageFunction({
label,
ruleParams,
})
}).toThrow()
})
}
describe(`languageCodeParsed is an EMPTY string`, () => {
beforeEach(() => {
parseStringVariableSpy.mockReturnValue(``)
})
testLanguageCodeParsedFalsy()
})
describe(`languageCodeParsed is NULL`, () => {
beforeEach(() => {
parseStringVariableSpy.mockReturnValue(null)
})
testLanguageCodeParsedFalsy()
})
describe(`languageCodeParsed is UNDEFINED`, () => {
beforeEach(() => {
parseStringVariableSpy.mockReturnValue(undefined)
})
testLanguageCodeParsedFalsy()
})
})
})
})
})
In particular, this bit:
it(`SHOULD NOT call getLanguageName.`, () => {
try {
VALIDATION_ERROR_MESSAGES.multilingual_unique.messageFunction({
label,
ruleParams,
})
} catch (error) {
// Ignore the error
}
expect(getLanguageNameSpy).not.toHaveBeenCalled()
})
Every time, Sonar warns us on this kind of thing, and while I’d understand the warning if this were source code, this is a unit test. I really don’t think it should.