Шутка, чтобы соответствовать каждому объекту в массиве

#jestjs

Вопрос:

Я хочу проверить, содержит ли каждый объект в массиве свойство «a», значением которого является число.

 
  test('a must be number always', () => {
        let response = [{ a: 'asdasd', y: 2 }, { a: 12 }];
        expect(response).toEqual(
            expect.arrayContaining([
                expect.objectContaining({ a: expect.any(Number) })
            ])
        );
    });
 

Этот приведенный выше случай является проходным, потому что jest может найти по крайней мере 1 объект, содержащий свойство » a » с номером. Но я хочу, чтобы у каждого объекта был номер.Что-то похожее на Array.every .

В продолжении выше, как мы можем сопоставить свойство объекта с числом или строкой.

   test('a must be either number or String always', () => {
        let response = [{ a: 'asdasd', y: 2 }, { a: true }];
        expect(response).toEqual(
            expect.arrayContaining([
                expect.objectContaining({ a: expect.any(Number) or expect.any(String) or `expect a = 4` })
            ])
        );
    });
 

Ответ №1:

Я только начал использовать Jest и, честно говоря, я очень разочарован названиями его методов и их вводящей в заблуждение семантикой … Мне не хватает композиционности и выразительности @hapi/code или chai.

Тем не менее, вы можете реализовать свои тесты следующим образом, но я был бы рад, если бы кто-нибудь показал лучший способ сделать это:

 test('a must be number always', () => {
  let response = [{ a: 'asdasd', y: 2 }, { a: 12 }];
  response.forEach(el => {
    // check each element of the array, individually
    expect(el).toEqual(expect.objectContaining({ a: expect.any(Number) }))
  })
});

// Message shows no reference to the array
// expect(received).toEqual(expected) // deep equality
// Expected: ObjectContaining {"a": Any<Number>}
// Received: {"a": "asdasd", "y": 2}
 

Альтернативным способом, более близким к вашему исходному коду, может быть следующее:

 test.only('a must be number always', () => {
  let response = [{ a: 'q', y: 2 }, { a: 12 }];

  expect(response).toEqual(
    // the array must NOT contain an element that does NOT contain {a: _number_}
    expect.not.arrayContaining([
      expect.not.objectContaining({a: expect.any(Number)})
    ])
  );
});


// Message references the array, but in a cryptic way:
// expect(received).toEqual(expected) // deep equality
// Expected: ArrayNotContaining [ObjectNotContaining {"a": Any<Number>}]
// Received: [{"a": "q", "y": 2}, {"a": 12}]