javascript:S2486 should not be applied to unit tests

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.

Hi,

In the name of i-dotting, can you give your context for this? I.e. are you on SonarQube Cloud? SonarQube for IDE (flavor and version)? SonarQube self-managed (flavor and version)?

 
Thx,
Ann

Sorry for the delay. I didn’t see the notification. I am using SonarQube for IDE (11.10.0.83942) in WebStorm (2025.3.1.1).

SonarQube for IDE is linked to SonarQube Self-managed (Community Build
v25.2.0.102705) - which I know is not up to date, but I don’t have power over this as I’m just a developer

Hi,

The current version of SonarQube for IntelliJ (formerly SonarLint) is 11.11. Can you upgrade and see if this is still replicable?

 
Thx,
Ann

Actually, I’m realizing I’m not getting warned in my IDE. I think something might be wrong with my config. But when the SonarQube task runs on my merge request, I’m absolutely getting issues.

Hi,

What’s your context for where you are seeing the issue? I.e. are you on SonarQube Cloud? SonarQube self-managed (flavor and version)?

 
Thx,
Ann

That would be in the branch analysis that’s triggered by merge requests. It’s SonarQube Self-managed (Community Build
v25.2.0.102705)

I realize that’s very out of date, but I don’t have much power over when we update.

Hi,

Thanks for the context. Unfortunately, only the latest version of Community Build is supported. Currently that’s 26.1. Can you upgrade and see if you’re still getting this?

 
Thx,
Ann

I don’t know when our Ops team will be able to update but I’ll be back with news when they do.

1 Like