Как проверить дату создания строки MySQL в интеграционном тесте JavaScript? - PullRequest
1 голос
/ 08 апреля 2020

Я пишу интеграционный тест для метода «create» в модуле доступа к данным Node, который работает с базой данных MySQL. Наша таблица MySQL имеет поле created_at, тип timestamp, по умолчанию CURRENT_TIMESTAMP. Скажем, моя таблица выглядит примерно так:

CREATE TABLE `some_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `column1` varchar(255) DEFAULT NULL,
  `column2` int(11) DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
)

Что я хотел бы сделать, это проверить, что поле created_at установлено так, как ожидалось, скажем, что оно такое же или после того, как тест начался выполнение. Я пытаюсь использовать isSameOrAfter Момента с его utc() способностью разбора, но я не могу понять это. Скажем, мой тест выглядит примерно так:

test('created_at is set on creation', async () => {
  // must use UTC since CURRENT_TIMESTAMP is UTC
  const now = moment.utc();
  // newObject is a POJO of the newly created row in some_table
  const newObject = await someTableLib.create(args);
  // this does not work for some reason
  expect(moment.utc(newObject.created_at).isSameOrAfter(now)).toBe(true);
})

Я также пытался не использовать utc() для анализа даты базы данных:

expect(moment(newObject.created_at).isSameOrAfter(now)).toBe(true);

Как лучше всего проверить эту базу данных устанавливает created_at как ожидалось?

РЕДАКТИРОВАТЬ
Некоторые примеры значений, которые я вижу, когда добавляю некоторые операторы console.log() (хотя я не уверен, как лучше сравнить значения из Момента в console.log):

console.log(newObject.created_at);
// 2020-04-08T14:50:46.000Z
console.log(moment.utc(newObject.created_at).format('YYYY-MM-DD HH:mm:ss');
// 2020-04-08 14:50:46
console.log(now.format('YYYY-MM-DD HH:mm:ss');
// 2020-04-08 14:50:46

РЕДАКТИРОВАТЬ 2
Теперь я полностью запутался. Если я форматирую моментные объекты, а затем заново инициализирую их как моментные объекты, ТОГДА сравниваю их, это работает:

const testStart = moment(now.format('YYYY-MM-DD HH:mm:ss'));
const created = moment(moment.utc(newObject.created_at).format('YYYY-MM-DD HH:mm:ss'));
expect(created.isSameOrAfter(testStart)).toBe(true);  // this passes!!

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Кажется, что есть несоответствие во времени сервера (сервер БД) и клиента (сервер приложений) в миллисекундах или долях. В этом случае кажется, что время сервера опережает время клиента, которое всегда возвращает created_at (с сервера) меньше now (от клиента в тестовом примере).

В порядке Чтобы решить эту проблему, мы можем передать точность функции isSameOrAfter момента как «минута» или «секунда», чтобы она игнорировала меньшие доли при сравнении двух. Пожалуйста, обратитесь к документации (https://momentjscom.readthedocs.io/en/latest/moment/05-query/05-is-same-or-after/), чтобы узнать, как передать точность этой функции.

0 голосов
/ 09 апреля 2020

Вместо использования момента js вы можете попробовать использовать отметку времени unix, которая поддерживается MySQL (в секундах) и javascript (в мс)

test('difference in time should be within a second', () => {
  x = query("SELECT UNIX_TIMESTAMP(created_at) AS x FROM ...");
  expect(x).toBeCloseTo(Date.now() / 1000, 0);
});
...