开玩笑:测试类型或null

时间:2018-07-02 09:50:57

标签: javascript node.js jestjs

我有一个测试,我想测试我接收到的对象值类型是否与模式匹配。可能是对于某些键,我可能会收到一些东西或为空

到目前为止,我已经尝试过

  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
    };
  }
};

在我的测试中

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

我也尝试了bebeE​​qual和其他东西。...

我的测试通过

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

我不知道该怎么办.. 如果有人有想法 谢谢

3 个答案:

答案 0 :(得分:2)

我实际上根本不了解Jest,但是我看了一下,因为目前代码测试使我感兴趣。

根据我在expect.extend documentation中看到的内容,看来您使用的是错误的方式。当前,您正在为其提供对toBeTypeOrNull的调用结果,例如在birthDate: expect.extend(toBeTypeOrNull("Date")),中,而不是函数本身。这可能导致调用具有未定义的参数,因为该调用使用2个参数(received, argument)进行了声明。然后argument是未定义的,因此您无法在自定义函数中执行expect.any(argument)

根据我在文档中看到的内容,应该以一个包含所有自定义函数的对象开头调用extend,以便以后使用。尝试使用此代码,如果出现问题,请毫不犹豫地发表评论:

更新:了解objectContainingtoMatchObjectsee this answer

之间的区别
expect.extend({
  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
      };
    }
  }
});

//your code that starts the test and gets the data
  expect(res.result.data).toMatchObject({
    birthDate: expect.toBeTypeOrNull(Date),
    contact: expect.toBeTypeOrNull(String),
    createdAt: expect.any(Date),
    firstName: expect.any(String),
    id: expect.any(Number),
    idDevice: expect.toBeTypeOrNull(Number),
    information: expect.toBeTypeOrNull(String),
    lastName: expect.any(String),
    macAddress: expect.toBeTypeOrNull(String),
    updatedAt: expect.any(Date),
    // state: toBeTypeOrNull()
  });

答案 1 :(得分:1)

所有先前给出的响应在其实现中均未正确使用expect(),因此它们实际上并没有起作用。

您想要的是一个玩笑匹配器,其作用类似于any(),但是接受空值,并且在实现中不使用expect()函数。您可以通过基本上复制原始any()实现(来自Jasmine)来实现此扩展,但是在开始时添加了null测试:

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)}`
    };
  }
});

将以上内容放入.js文件中,然后使用jest setupFilesAfterEnv配置变量指向该文件。现在,您可以运行测试,例如:

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

expect(object).toEqual(schema);

答案 2 :(得分:0)

我一直在寻找可以验证任何类型或null的东西,但碰到了这个答案,正确率为95%。问题出在行中,因为期望未能尝试将nullargument进行比较。

const pass = expect(received).toEqual(expect.any(argument));

作为奖励,我创建了一个toBeObjectContainingOrNull。这是我的代码:

const expect = require("expect");

const okObject = {
    message: () => "Ok",
    pass: true
};

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

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

module.exports = { expect };

然后您可以按以下方式使用toBeObjectContainingOrNull

const userImageSchema = {
    displayName: expect.any(String),
    image: expect.toBeObjectContainingOrNull({
        type: "Buffer",
        data: expect.any(Array)
    }),
    orgs: expect.any(Array)
};

我希望它会有所帮助。