Search code examples
typescriptunit-testingts-jest

How to mock object with the help of interface in typescript unit testing?


Is there any way to mock ts object using its interface in unit testing (for example i use jest)? I try to find solution and stumbled upon this library ts-auto-mock, but it will no longer be supported.

Is there any solution to such problem?

A short description of what I need:

I have interface of object:

enum Sex {
  Male,
  Female
}

interface IdName {
  id: string;
  name: string;
}

interface IUser extends IdName  {
  login: string;
  age: string;
  sex: Sex;
  location: {
    city: IdName,
    country: IdName,
    region: IdName,
  }
}

Is there some way (library) to create a mock object from the interface for testing in my function?

For example only by IUser interface i'll get:

const mockUser = createMockByInterface<IUser>();

// mockUser
{
  id: <generated string>,
  name: <generated string>,
  login: <generated string>,
  age: <generated number>,
  sex: <random Sex from Sex enum>,
  location: {
    city: {
      id: <generated string>,
      name: <generated string>,
    },
    country: {
      id: <generated string>,
      name: <generated string>,
    },
    region: {
      id: <generated string>,
      name: <generated string>,
    },
  }
}

Solution

  • You could create a function for every interface.

    If you name the function the same as the interface (like the example) typescript will automatically take the right one. But you can the function however you want.

    With the partial you can give the function a part you want a value and the rest gets the default value.

    Example

    interface IUser extends IdName  {
      login: string;
      age: string;
      sex: Sex;
      location: {
        city: IdName,
        country: IdName,
        region: IdName,
      }
    }
    
    function IUser(object?: Partial<IUser>): IUser {
      return {
        login: '',
        age: '',
        sex: Sex.Male,
        location: {
          city: IdName(),
          country: IdName(),
          region: IdName(),
        },
        ...object
      }
    }
    

    You can use the interface the same as before, and if you need a new Object you could do this:

    Default Object

    const myObject: IUser = IUser();
    

    With Values

    const myObject: IUser = IUser({
      age: '30'
    })
    

    Every property that is not set will get the default value