Unit Testing - Creating Re-Usable Mock Data

Angular: The Full Gamut Edition

Charlie Greenman
September 13, 2020
2 min read

Unit Testing Maintainability

Unit testing in many enterprise settings is an interesting phenomenon. In particular, actual code for features will be very clean, maintainable, and stick to very particular conventions. However, unit testing can be a bit all over the place. This is one of a number of articles that will be written with regards to unit testing.


Function Composition

With regards to creating re-usable data, there are two options. One can use a function to generate a mock. Alternatively, one can use a spread operator. For the most part, I prefer a function to generate a mock. It gives the option to specify parameters to be passed through. Depending on the function, a spread operator will be used, to make sure data can be properly passed through.

// this interface is in our users.interface.ts file
export interface User { 
  id: string;
  name: string;
  location: string;
}
// this interface is in our users.interface.ts file
export interface Users { 
  users: User[]
}
let generateMockUserData: User = (data: user) => {
  user[id]: {
    user
  } 
}
let generateMockUsersData: Users = (data: user | user[]) => {
  users: {
    ... data 
  }
}

By using the simple functions above, properly type annotated, we have the option to generate mocked data that is unique to our interface. In addition, we have the ability to pass in data as it is unique to our specific use case.


Core Constants — The Two Constant Rule

In addition to having function composition tied to our interfaces, odds are that the data being passed in might have the same signature time and time again. Enter the three constant rule:

const genericMockUsers: Users = {
  generateMockUsersData(
    generateMockUserData({ 
      id: '123',
      name: 'Charles',
      location: 'New York'
    }),
    generateMockUserData({
      id: '246',
      name: 'Lisa',
      location: 'London'
    }),
    generateMockUserData({
      id: '468',
      name: 'Yoda',
      location: 'Canary Islands'
    }),
  )
}
const genericMockUser: User = { 
  generateMockUserData({
   id: '123',
   name: 'Charles', location: 'New York'
  }),
}

At the end of the day, you should have two interfaces, two functions, and two constants for use in mocking data throughout the unit test. Any new data that should be created for use in the unit test, should be specific to unit test’s it block.

Thank you for reading, and if you have any questions or comments, by all means, feel free to comment here.

More articles similar to this

footer

Razroo is committed towards contributing to open source. Take the pledge towards open source by tweeting, #itaketherazroopledge to @_Razroo on twitter. One of our associates will get back to you and set you up with an open source project to work on.