[Unit testing + Jest] Use jest-in-case to Reduce Duplication and Improve Test Titles

Jest has a test-generation feature built-in called test.each which is great, but I don’t particularly like it’s API. Instead, we’re going to use an open source project called jest-in-case which gives us a really nice API for generated tests and improved error messages. Let’s try that library out for our isPasswordAllowed tests here.

 

// From
import {isPasswordAllowed} from '../auth'

describe('isPasswordAllowed', () => {
  const allowedPwds = ['!aBc123']
  const disallowedPwds = {
    'too short': 'a2c!',
    'no alphabet characters': '123456',
    'no numbers': 'ABCdef!',
    'no uppercase letters': 'abc123!',
    'no lowercase letters': 'ABC123!',
    'no non-alphanumeric characters': 'ABCdef123',
  }
  allowedPwds.forEach((pwd) => {
    test(`allow ${pwd}`, () => {
      expect(isPasswordAllowed(pwd)).toBeTruthy()
    })
  })
  Object.entries(disallowedPwds).forEach(([key, value]) => {
    test(`disallow - ${key}: ${value}`, () => {
      expect(isPasswordAllowed(value)).toBeFalsy()
    })
  })
})

 

to:

import cases from 'jest-in-case'
import {isPasswordAllowed} from '../auth'

cases(
  'isPasswordAllowed: valid passwords',
  ({password}) => {
    expect(isPasswordAllowed(password)).toBe(true)
  },
  {
    'valid password': {
      password: '!aBc123',
    },
  },
)

cases(
  'isPasswordAllowed: invalid passwords',
  ({password}) => {
    expect(isPasswordAllowed(password)).toBe(false)
  },
  {
    'too short': {
      password: 'a2c!',
    },
    'no letters': {
      password: '123456!',
    },
    'no numbers': {
      password: 'ABCdef!',
    },
    'no uppercase letters': {
      password: 'abc123!',
    },
    'no lowercase letters': {
      password: 'ABC123!',
    },
    'no non-alphanumeric characters': {
      password: 'ABCdef123',
    },
  },
)

(Not necessary)

 

 

Even with jest-in-case there can be a little boilerplate and you can easily side-step that by creating a simple function that allows you to write test cases that are more suited for your use case. Let’s give that a try!

import cases from 'jest-in-case'
import {isPasswordAllowed} from '../auth'

function casify(obj) {
  return Object.entries(obj).map(([name, password]) => ({
    name: `${password} - ${name}`,
    password,
  }))
}

cases(
  'isPasswordAllowed: valid passwords',
  ({password}) => {
    expect(isPasswordAllowed(password)).toBe(true)
  },
  casify({'valid password': '!aBc123'}),
)

cases(
  'isPasswordAllowed: invalid passwords',
  ({password}) => {
    expect(isPasswordAllowed(password)).toBe(false)
  },
  casify({
    'too short': 'a2c!',
    'no letters': '123456!',
    'no numbers': 'ABCdef!',
    'no uppercase letters': 'abc123!',
    'no lowercase letters': 'ABC123!',
    'no non-alphanumeric characters': 'ABCdef123',
  }),
)

posted @ 2021-08-05 18:51  Zhentiw  阅读(42)  评论(0编辑  收藏  举报