Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest : Testing for type or null

I have a test where i want to test if my received object value types match a schema. Prob is that for some keys i may receive something or null

I tried this so far

  const attendeeSchema = {
  birthDate: expect.extend(toBeTypeOrNull("Date")),
  contact: expect.extend(toBeTypeOrNull(String)),
  createdAt: expect.any(Date),
  firstName: expect.any(String),
  id: expect.any(Number),
  idDevice: expect.extend(toBeTypeOrNull(Number)),
  information: expect.extend(toBeTypeOrNull(String)),
  lastName: expect.any(String),
  macAddress: expect.extend(toBeTypeOrNull(String)),
  updatedAt: expect.any(Date),
  // state: toBeTypeOrNull()
};

    const toBeTypeOrNull = (received, argument) => {
  const pass = expect(received).toEqual(expect.any(argument));
  if (pass || received === null) {
    return {
      message: () => `Ok`,
      pass: true
    };
  } else {
    return {
      message: () => `expected ${received} to be ${argument} type or null`,
      pass: false
    };
  }
};

and on my test

 expect(res.result.data).toBe(attendeeSchema);

i also tried tobeEqual and other stuff....

my test doenst pass with

TypeError: any() expects to be passed a constructor function. Please pass one or use anything() to match any object.

I have no idea what to do here.. If someone has an idea Thanks

like image 934
kikiwie Avatar asked Jul 02 '18 09:07

kikiwie


1 Answers

All the previously given responses improperly use expect() in their implementation, so they don't really work.

What you want is a jest matcher that works like any() but accepts null values and doesn't use expect() functions in its implementation. You can implement this as an extension by basically copying the original any() implementation (from Jasmine), but with a null test added to the start:

expect.extend({
  nullOrAny(received, expected) {
    if (received === null) {
      return {
        pass: true,
        message: () => `expected null or instance of ${this.utils.printExpected(expected) }, but received ${ this.utils.printReceived(received) }`
      };
    }

    if (expected == String) {
      return {
        pass: typeof received == 'string' || received instanceof String,
        message: () => `expected null or instance of ${this.utils.printExpected(expected) }, but received ${ this.utils.printReceived(received) }`
      };        
    }

    if (expected == Number) {
      return {
        pass: typeof received == 'number' || received instanceof Number,
        message: () => `expected null or instance of ${this.utils.printExpected(expected)}, but received ${this.utils.printReceived(received)}`
      };
    }

    if (expected == Function) {
      return {
        pass: typeof received == 'function' || received instanceof Function,
        message: () => `expected null or instance of ${this.utils.printExpected(expected)}, but received ${this.utils.printReceived(received)}`
      };
    }

    if (expected == Object) {
      return {
        pass: received !== null && typeof received == 'object',
        message: () => `expected null or instance of ${this.utils.printExpected(expected)}, but received ${this.utils.printReceived(received)}`
      };
    }

    if (expected == Boolean) {
      return {
        pass: typeof received == 'boolean',
        message: () => `expected null or instance of ${this.utils.printExpected(expected)}, but received ${this.utils.printReceived(received)}`
      };
    }

    /* jshint -W122 */
    /* global Symbol */
    if (typeof Symbol != 'undefined' && this.expectedObject == Symbol) {
      return {
        pass: typeof received == 'symbol',
        message: () => `expected null or instance of ${this.utils.printExpected(expected)}, but received ${this.utils.printReceived(received)}`
      };
    }
    /* jshint +W122 */

    return {
      pass: received instanceof expected,
      message: () => `expected null or instance of ${this.utils.printExpected(expected)}, but received ${this.utils.printReceived(received)}`
    };
  }
});

throw the above in a .js file, then point to that file with the jest setupFilesAfterEnv configuration variable. Now you can run your tests like:

const schema = {
  person: expect.nullOrAny(Person),
  age: expect.nullOrAny(Number)
};

expect(object).toEqual(schema);

like image 64
Eric Lambrecht Avatar answered Oct 02 '22 13:10

Eric Lambrecht