Javascript pure function & Jesting
Tags: react, testing, webdev, codenewbie
Published: 2020-03-30 06:42:41

> Of all things you can test, the easiest thing is a pure function because they require no setup or teardown. In this exercise, i want to pen down my take on testing a pure function using one of the functions we use in my project isPasswordEnteredValid? :smiley:.

isPasswordEnteredValid? is a function which takes a string and returns a boolean.


```js

// For simplicity sake RegEx's are edited.

const checkLengthRegex = /(^.{8,}$)/
const checkNonAlphaNumeric = /\W/
const checkUpCaseRegex = /[A-Z]/
const checkLowerCaseRegex = /[a-z]/
const checkIntRegex = /(?=.*[0-9])/
const checkLength = (pwd: string) => checkLengthRegex.test(pwd)
const checkUpCase = (pwd: string) => checkUpCaseRegex.test(pwd)
const checkLowerCase = (pwd: string) =>  checkLowerCaseRegex.test(pwd)
const checkNonAlphaNumericCase = (pwd: string) => checkNonAlphaNumeric.test(pwd)
const checkInt = (pwd: string) => checkIntRegex.test(pwd)

function isPasswordEnteredValid(password) {
  return (
    checkLength(password) &&
    checkNonAlphaNumeric(password) &&
    checkIntRegex(password) &&
    checkUpCase(password) &&
    checkLowerCase(password)
  )
}

```

For most of the util functions like above general approach is to add a 'test' block for each of the use case.

```js

describe('isPasswordEnteredValid', () => {

    test('returns false if password length is < 8', () => {
        expect(isPasswordEnteredValid('pra4!')).toBeFalsy()
    })

    test('returns false if password has no alphabets', () => {
        expect(isPasswordEnteredValid('20034059!')).toBeFalsy()
    })

    test('returns false if password has no numbers ', () => {
        expect(isPasswordEnteredValid('Pranava')).toBeFalsy()
    })

    test('returns false if password has no uppercase letters', () => {
        expect(isPasswordEnteredValid('pranava!')).toBeFalsy()
    })

    test('returns false if password has no lower case letters', () => {
        expect(isPasswordEnteredValid('PRANAVA1!')).toBeFalsy()
    })

    test('returns false if password has no non-alphanumeric characters', () => {
        expect(isPasswordEnteredValid('Pranava')).toBeFalsy()
    })

    test('returns true if the password is strong', () => {
        expect(isPasswordEnteredValid('Balugari034059!')).toBeTruthy()
    })
})
```

Another approach is to group the happy path and unhappy path test cases using an array or object.

```js

describe('isPasswordEnteredValid', () => {
  const validPasswords = ['Balugari034059!']
  const inValidPasswords = [
    'pra4!',
    '20034059!',
    'Pranava',
    'pranava!',
    'PRANAVA1!',
    'Pranava',
  ]

  validPasswords.forEach(password => {
    test(`allows ${password} >>`, () => {
      expect(isPasswordEnteredValid(password)).toBeTruthy()
    })
  })

  inValidPasswords.forEach(password => {
    test(`disallows ${password} >>`, () => {
      expect(isPasswordEnteredValid(password)).toBeFalsy()
    })
  })
})
```

I tend to use above mentioned conventions to test a javascript functions at my work. Recently, i came across jest-in-case library which provides another convention to test javascript functions.

```js

import cases from 'jest-in-case'

const validPasswordUseCases = {
   'valid password': {
      password: 'Balugari034059!',
    },
}

const invalidPasswordUseCases = {
    '< 8 characters': {
      password: 'pra4!',
    },
    'no alphabets': {
      password: '20034059!',
    },
    'no numbers': {
      password: 'Pranava!',
    },
    'no upcase characters': {
      password: 'pranava!',
    },
    'no lowercase characters': {
      password: 'PRANAVA1!',
    },
    'no non-alphanumeric characters': {
      password: 'Pranava',
    },
}

// cases here provide abstraction to the function
// to be tested.
cases(
  'isPasswordEnteredValid: valid passwords',
  ({pwd}) => {
    expect(isPasswordEnteredValid(pwd)).toBeTruthy()
  },
  validPasswordUseCases,
)

cases(
  'isPasswordEnteredValid?: invalid passwords',
  ({password}) => {
    expect(isPasswordEnteredValid(password)).toBe(false)
  },
  invalidPasswordUseCases,
)

```

## Wrapping up

I hope this article becomes a reference for developers who are looking to write tests for javascript util functions.

I will appreciate the constructive feedback about the article. Please share approaches you have come across in your experience when testing util functions in javascript. 

Thanks to Kent C Dodds and Frontendmasters courses :)