Утверждение ошибки типа потока в модульных тестах
Мы используем Flow для статической проверки типов в JavaScript. Типы потока могут быть сложными, и у нас были проблемы, когда мы думали, что у нас есть хорошая защита статического типа от уродливых объектов, но проблемы аннотации потока означали, что проверка типов на самом деле не улавливала проблемы.
Чтобы предотвратить эту проблему, я хотел бы написать основанные на типах "модульные тесты", которые могут статически утверждать наши предположения о защите типов. Это легко, если я хочу подтвердить "правильный" случай, используя утверждения типа:
type User = {|
name: string
|};
const user = {name: "Bob"};
(user: User);
Это пройдет, если user
является действительным User
и провалить проверку типа, если это не так.
Однако, чтобы утверждать фактическую проверку типов защиты, мы должны иметь возможность утверждать ошибки потока. Например, допустим, я хотел убедиться, что это не так:
const user = {name: "Bob", age: 40};
Я могу пройти тест с
// $ExpectError
const user = {name: "Bob", age: 40};
но я не могу заставить его потерпеть неудачу с
// $ExpectError
const user = {name: "Bob"};
Очевидно, этот пример довольно тривиален, но более сложные типы (например, с обобщениями) могут выиграть от этого типа тестирования.
Варианты, которые я рассмотрел:
- Я мог бы потенциально бежать
flow
как внешний процесс для определенных файлов, а затем утверждают, что он возвратил ошибку, но для этого потребуется один файл для каждого теста - Я мог бы использовать поток выполнения для доступа к типам во время выполнения и использовать их в модульных тестах, но это не дает статических утверждений
Есть ли способ статически утверждать, что утверждение потока должно потерпеть неудачу, и выдать ошибку, если это не так?
1 ответ
Чтобы утверждать, что определенные строки кода в ваших модульных тестах должны вызывать ошибки потока, просто напишите комментарий подавления ошибок потока над этими строками, а затем выполните команду flow check --max-warnings 0
на всю вашу папку модульных тестов (или всю вашу кодовую базу) и утверждайте, что команда имеет статус 0 выхода (без ошибок или предупреждений). Вам не нужно запускать команды для каждого файла модульного теста в отдельности.
В качестве документации дляsuppress_comment
говорит, что Flow выдаст предупреждение, если вы напишите комментарий подавления, такой как // $FlowExpectError
выше линии, которая фактически не вызывает ошибку потока.
Предполагая, что вы определили suppress_comment
чтобы понять $FlowExpectError
в качестве комментария подавления, вот как будут выглядеть ваши юнит-тесты:
// this type definition could be imported from another file
type User = {|
name: string
|};
// Check that Flow doesn’t raise an error for correct usages
const user = {name: "Bob"};
// Check that Flow does raise an error for incorrect usages
// $FlowExpectError
const user = {name: "Bob", age: 40};
Если вы бежите flow check --max-warnings 0
в папке, содержащей этот файл и команда завершается успешно, то ваши тесты для вашего User
Тип пройден.