Jest: Проверить объект, массив или строку.

Созданный на 3 мая 2017  ·  29Комментарии  ·  Источник: facebook/jest

Есть ли способ проверить, является ли компонент объектом, массивом или строкой? Это было бы похоже на chai 'should.be.a' Пример: validationResult.SSN [0] .should.be.a ('string').

Самый полезный комментарий

Простое расширение toBeType для тех, кто этого хочет

expect.extend({
    toBeType(received, argument) {
        const initialType = typeof received;
        const type = initialType === "object" ? Array.isArray(received) ? "array" : initialType : initialType;
        return type === argument ? {
            message: () => `expected ${received} to be type ${argument}`,
            pass: true
        } : {
            message: () => `expected ${received} to be type ${argument}`,
            pass: false
        };
    }
});

describe("testing extended expect", () => {
    it("tests normal types correctly", () => {
        expect("").toBeType("string");
        expect({}).toBeType("object");
        expect(1).toBeType("number");
    });
    it("tests array types correctly", () => {
        expect([]).toBeType("array");
    });
    it("works with promises", () => {
        expect(Promise.resolve([])).resolves.toBeType("array");
    });
});

Довольно просто реализовать. Действительно должно быть в core tbh.

Примечание. Если вы помещаете это расширение в свои установочные файлы, вы хотите, чтобы он был в setupTestFrameworkScriptFile NOT setupFiles (поскольку расширение доступно только в первом случае)

Все 29 Комментарий

Нет, нет. Вы найдете список всех доступных сопоставителей здесь: https://facebook.github.io/jest/docs/en/expect.html

Вы также можете использовать для этого простой JavaScript или вспомогательную библиотеку, например lodash :

test('name', () => {
  // array
  expect(Array.isArray(['value'])).toBe(true);
  // string
  expect(typeof 'value').toBe('string');
  // object
  expect({value: 'value'}).toBeTruthy();
  expect(typeof {value: 'value'}).toBe('object');
})

Второстепенный момент - это не помогает с результатами обещаний.

expect(somePromise).resolves.toBe(...) на данный момент нет возможности проверить тип. Если вам все равно, что это за содержимое , а просто то, что это строка. Я надеялся, что expects.stringContaining("") можно обойти, но это тоже не сработало.

@abritinthebay Я как раз в такой ситуации, и это первый результат в Google, может быть, его нужно открыть заново?

Конечно, следует подумать еще немного. Мое обходное решение заключалось в том, чтобы добавить в цепочку, чтобы выполнялась часть typeof . например:

expect(somePromise.then(data => typeof data)).resolves.toBe("object");

работает, но не совсем чисто.

@thymikee Проверка типов вещей - достаточно распространенный вариант использования (универсальный),

Это expect(Array.isArray(['value'])).toBe(false); не работает с

expect(received).toBe(expected)
    Expected value to be (using ===):
      false
    Received:
      true. 

Таким образом, мы либо получаем ужасные сообщения с утверждениями, либо нам приходится расширять Jest для поддержки такого рода проверок. Разве для сопровождающих Jest не имеет смысла сделать это один раз, в отличие от каждого человека, который использует эти функции, чтобы реализовать их самостоятельно?

Создайте свои собственные сопоставители с помощью expect.extend затем опубликуйте как модуль npm. Если он станет популярным, мы можем со временем объединить его с ядром Jest;)

Простое расширение toBeType для тех, кто этого хочет

expect.extend({
    toBeType(received, argument) {
        const initialType = typeof received;
        const type = initialType === "object" ? Array.isArray(received) ? "array" : initialType : initialType;
        return type === argument ? {
            message: () => `expected ${received} to be type ${argument}`,
            pass: true
        } : {
            message: () => `expected ${received} to be type ${argument}`,
            pass: false
        };
    }
});

describe("testing extended expect", () => {
    it("tests normal types correctly", () => {
        expect("").toBeType("string");
        expect({}).toBeType("object");
        expect(1).toBeType("number");
    });
    it("tests array types correctly", () => {
        expect([]).toBeType("array");
    });
    it("works with promises", () => {
        expect(Promise.resolve([])).resolves.toBeType("array");
    });
});

Довольно просто реализовать. Действительно должно быть в core tbh.

Примечание. Если вы помещаете это расширение в свои установочные файлы, вы хотите, чтобы он был в setupTestFrameworkScriptFile NOT setupFiles (поскольку расширение доступно только в первом случае)

Спасибо @abritinthebay

Поэтому я завернул это в модуль npm, если люди этого захотят:

https://www.npmjs.com/package/jest-tobetype

describe("assertion framework", ()=> {
 it("should check primitive types", () => {
   expect(expect.toBeA).toBeA("function")
  })
})

Не удалось: ожидать (...). ToBeA не является функциейTypeError: expect (...). ToBeA не является функцией

https://github.com/jest-community/jest-extended есть все сопоставители типов, которые вам могут понадобиться (я думаю).

В своих тестах я использовал toBeInstanceOf :

expect($wrapper.vm.countries).toBeInstanceOf(Array);

Затем создайте свои собственные сопоставители с expect.extend и опубликуйте как модуль npm. Если он станет популярным, мы можем со временем объединить его с ядром Jest;)

Да, и можете написать свой собственный фреймворк для шуток, пока вы занимаетесь этим.

Этот вопрос может превзойти худшие ответы, которые вы можете получить на GitHub.

Итак, @abritinthebay сделал именно то @thymikee (что было намного больше, чем стандартный запрос на

Теперь, когда эта храбрая душа проделала всю работу, когда мы, наконец, сможем получить этот сопоставитель (без необходимости устанавливать еще одну библиотеку)? Сопровождающие все еще настаивают на том, что это не относится к Jest, или это просто выпало из их поля зрения?

Мы довольно строги в отношении того, что входит в состав ядра, и обычно не добавляем сахаросодержащие добавки. Ядро Jest - это довольно большая архитектура, и каждый добавляемый сопоставитель увеличивает стоимость обслуживания.

Для сахара мы обычно рекомендуем https://github.com/jest-community/jest-extended.

Сахар одного человека - это действительно полезная и логическая особенность другого человека (или, в данном случае, как минимум семи других), которая принадлежит основной библиотеке.

Очевидно, что как сопровождающий ваш голос превосходит все наши, и у вас есть всевозможные опасения, которых нет у нас, поэтому я полностью это уважаю. Но я просто прошу вас посмотреть, почему все здесь считают, что эта функция принадлежит основной библиотеке (настолько сильно, что один человек перепрыгнул через несколько обручей, чтобы написать код для вас). В этом есть необходимость, и если вы проигнорируете это, пользователи основной библиотеки Jest (и будем честными, 90% из них даже не услышат о jest-extended) проиграют.

.to.be.an.instanceOf не будет тем, сколько пользователей думают о проверке типов, поэтому для этих пользователей, даже если вы считаете это сахаром, вы фактически лишаете их возможности проверять типы в Jest без дополнительной библиотеки.

Да, я тебя слышу. Чтобы быть ясным, под «сахаром» я имел в виду синтаксис, который разработан, чтобы упростить чтение или выражение . Сахар по определению - это вариант уже существующей функции.

В этом случае мы имеем:

// Supported
expect(typeof foo).toBe('string');

// Proposed Sugar
expect(foo).toBeType('string');

Это не значит, что мы не поддерживаем типы проверки. Мы делаем. Мы поддерживаем первый вариант. В этом варианте используется базовый сопоставитель toBe котором мы потратили много времени на исправление ошибок и настройку сообщения, чтобы у пользователей был хороший опыт.

В jest-extended насчитывается около 60 сопоставителей, и многие из них - чистый сахар. Для любого из этих сопоставителей вы, вероятно, могли бы найти как минимум 7 других людей, которые сочли бы их действительно полезными, поэтому, если бы это была эвристика, которую мы использовали для добавления в ядро, мы, вероятно, потратили бы все свое время только на поддержку сопоставителей.

Чтобы быть полностью справедливым - большинство матчеров на каком-то уровне «сахар». Я имею в виду, что toBeGreaterThanOrEqual - это просто сахар для expect(foo >= bar).toBe(true);

Матчеры - это действительно почти весь_ сахар вокруг логических операторов;)

(Я говорю это не для того, чтобы копать, просто чтобы указать, что это ... очень размытая линия)

Как предположил abritinthebay, на самом деле речь идет не о сахаре, а о «необходимом» и «ненужном» (для основной библиотеки) сахаре. У вас есть куча людей в этой ветке, которые говорят: «Эй, возможность проверять все типы - это то, что должно быть в ядре библиотеки тестирования» (т.е. это необходимо).

Слушайте нас или не слушайте, опять же, как сопровождающий, у вас много других забот. Но я не думаю, что правильным ответом будет сказать: «ваш сахар - это просто по своей сути ненужный сахар» (это я пытаюсь перефразировать вас, а не вкладывать слова в ваш рот), когда это не присуще: это 100% ваш вызов, будь то шутка можно проверить все типы или нет из коробки.

как насчет, разве не сложно: P?

expect(Array.isArray(['your', 'array'])).toBe(true);

expect(typeof something === "object").toBe(true); 
// - or -
expect(something instanceof Object).toBe(true);

expect(typeof something === "string").toBe(true); 

@nahumzs Хотя это работает, проблема в том, что на вашем тестовом выходе при сбое будет написано «ожидаемое ложное значение будет истиной», что не очень полезно;)

Я думаю, это правильный путь :)

describe('type check', () => {
    test('should be type string', () => {
        expect(typeof '').toBe('string')
    })

    test('should be type number', () => {
        expect(typeof 10).toBe('number')
    })

    test('should be type boolean', () => {
        expect(typeof true).toBe('boolean')
    })

    test('should be type undefined', () => {
        expect(typeof undefined).toBe('undefined')
    })

    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
    })

    test('should be type function', () => {
        expect(typeof function() {}).toBe('function')
    })

    test('should be type null', () => {
        expect(typeof null).toBe('object')
    })
})

Я переработал реализацию, предоставленную @abritinthebay. Мне кажется, с ним немного комфортно работать.

`` javascript
ожидать.extend ({
/ ** @param { } получено
* @param {строка | строка []} аргумент
* @return {{pass: boolean, message: (function (): string)}}
* /
toBeType (получено, arg) {
const isCorrectType = arg => {
полученный constType = тип полученного;

        const checkForSingle = arg => {
            const type = receivedType === 'object'
                ? Array.isArray(received)
                    ? 'array'
                    : receivedType
                : receivedType;

            return type === arg;
        };

        const checkForArr = arg => {
            const reducer = (prev, curr) => prev || isCorrectType(curr).isCorrect;

            return arg.reduce(reducer, false);
        };

        return {
            receivedType,
            isCorrect: Array.isArray(arg)
                ? checkForArr(arg)
                : checkForSingle(arg)
        };
    };

    const {isCorrect, receivedType} = isCorrectType(arg);

    return {
        pass: isCorrect,
        message: () => {
            const toBe = Array.isArray(arg)
                ? arg.join(`' or '`)
                : arg;

            return `Expected '${received}' of '${receivedType}' type to be of '${toBe}' type(s)`;
        }
    };
}

});

Вы должны проверить мой модуль (ссылка выше). Это немного больше. Но если это работает для вас: используйте это!

Я думаю, это правильный путь :)

describe('type check', () => {
    test('should be type string', () => {
        expect(typeof '').toBe('string')
    })

    test('should be type number', () => {
        expect(typeof 10).toBe('number')
    })

    test('should be type boolean', () => {
        expect(typeof true).toBe('boolean')
    })

    test('should be type undefined', () => {
        expect(typeof undefined).toBe('undefined')
    })

    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
    })

    test('should be type function', () => {
        expect(typeof function() {}).toBe('function')
    })

    test('should be type null', () => {
        expect(typeof null).toBe('object')
    })
})

Он работает как шарм, а также более удобен для чтения и обслуживания в будущем.

Я думаю, это правильный путь :)

describe('type check', () => {
    test('should be type string', () => {
        expect(typeof '').toBe('string')
    })

    test('should be type number', () => {
        expect(typeof 10).toBe('number')
    })

    test('should be type boolean', () => {
        expect(typeof true).toBe('boolean')
    })

    test('should be type undefined', () => {
        expect(typeof undefined).toBe('undefined')
    })

    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
    })

    test('should be type function', () => {
        expect(typeof function() {}).toBe('function')
    })

    test('should be type null', () => {
        expect(typeof null).toBe('object')
    })
})
    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
        // passes
        expect(typeof ['foo', 'bar']).toBe('object')
        // passes
        expect(typeof null).toBe('object')
    })

😞

Вот почему я предлагаю свой аддон выше: позаботится об этом.

InstanceOf немного лучше, но подвержен аналогичным проблемам.

Ссылка на него:

https://www.npmjs.com/package/jest-tobetype

спасибо за решение @abritinthebay

Другое решение:

expect('example').toEqual(expect.any(String));
expect(123).toEqual(expect.any(String));

Второй не удастся:

    Expected: Any<String>
    Received: 123
Была ли эта страница полезной?
0 / 5 - 0 рейтинги