Структура ожиданий предоставляет возможность создавать тесты, основанные на взаимодействии (или поведении) . Ранее я писал о добавлении тестирования, основанного на взаимодействии, к ожиданиям ; однако примеры из этой записи блога были сосредоточены исключительно на тестировании взаимодействий, где каждый аргумент сопоставляется с использованием равенства. В этой записи я приведу примеры того, как каждый аргумент также может быть проверен с помощью класса, регулярного выражения, исключения или пользовательской функции.
При написании государственных тестовИспользуя ожидания, тип теста, который вы пишете, определяется исходя из ожидаемого значения. Если ожидаемое значение является регулярным выражением, ожидания будут проверять фактическое значение, чтобы увидеть, соответствует ли оно регулярному выражению. Если вы перешли в класс, ожидания будут проверять фактическое значение, чтобы увидеть, является ли он экземпляром этого класса. Если вы прошли исключение … вы поняли. Все, что я сказал выше, также верно для аргументов взаимодействия.
Давайте начнем с простого теста на основе взаимодействия:
(ns blog-expectations (:use expectations)) (expect (interaction (spit "/tmp/hello-world" "some data" :append true)) (do (spit "/tmp/somewhere-else" "nil") (spit "/tmp/hello-world" "some data" :append true)))
В приведенном выше примере мы вызываем функцию spit с точными аргументами, которые мы указали в нашем тесте. Этот тест пройдет; Однако нам пришлось указать точное местоположение файла и точные данные. Если по какой-то причине вы не можете точно указать аргумент, было бы неплохо иметь возможность указать столько, сколько вы можете.
В приведенном ниже примере мы все еще указываем точные данные, но мы только проверяем, что файл находится где-то в / tmp /.
(expect (interaction (spit #"/tmp/" "some data" :append true)) (do (spit "/tmp/somewhere-else" "nil") (spit "/tmp/hello-world" "some data" :append true)))
Как я упоминал ранее, мы также можем получить более общую информацию и проверить только класс аргумента. Например, если мы знали, что наши данные будут строкой, но мы не хотели точно указывать, что это за строка, то следующий тест поможет.
(expect (interaction (spit #"/tmp/" String :append true)) (do (spit "/tmp/somewhere-else" "nil") (spit "/tmp/hello-world" "some data" :append true)))
В то время как ожидания предоставляют вам множество опций по умолчанию, бывают ситуации, когда вы захотите написать собственный аргумент «matcher». В качестве надуманного примера давайте представим, что мы хотим проверить, является ли последний аргумент истинным или нулевым.
(defn true-or-nil? [x] (or (true? x) (nil? x))) ;; this test passes (expect (interaction (spit #"/tmp/" String :append true-or-nil?)) (do (spit "/tmp/somewhere-else" "nil") (spit "/tmp/hello-world" "some data" :append true))) ;; so does this test (expect (interaction (spit #"/tmp/" String :append true-or-nil?)) (do (spit "/tmp/somewhere-else" "nil") (spit "/tmp/hello-world" "some data" :append nil))) ;; this test fails (expect (interaction (spit #"/tmp/" String :append true-or-nil?)) (do (spit "/tmp/somewhere-else" "nil") (spit "/tmp/hello-world" "some data" :append "not true or nil")))
Одна из лучших особенностей ожиданий — это отчеты об ошибках, и такая же логика отчетов об ошибках применяется к аргументам в случае неудачи теста на основе взаимодействия. Учитывая приведенный выше пример, вы получите следующее сообщение об ошибке.
failure in (success_examples.clj:204) : success.success-examples expected: (spit #"/tmp/" String :append true-or-nil?) got: 0 times -- got: (spit "/tmp/somewhere-else" "nil") "nil", "/tmp/somewhere-else" are in actual, but not in expected true_or_nil_QMARK, #"/tmp/", :append, String are in expected, but not in actual expected is larger than actual -- got: (spit "/tmp/hello-world" "some data" :append "s") - arg4: not true or nil
Как вы можете видеть, оба вызова сообщаются, и каждый аргумент имеет подробный отчет (если он не совпадает).
Наконец, ожидание обеспечивает и дополнительную функцию, которую можно использовать для проверки того, что определенные пары ключ / значение находятся в аргументе. Следующий пример на самом деле не имеет смысла, так как вы никогда не захотите передать карту в качестве последнего аргумента, но вам легко следовать в контексте этой записи в блоге.
(expect (interaction (spit String #"some da" keyword? (contains-kvs :a :b :c :d))) (spit "/tmp/hello-world" "some data" :append {:a :b :c :d :e :f}))
В приведенном выше примере, (содержит-kvs) используется, чтобы убедиться, что последний аргумент для плевания содержит пары ключ / значение: a: b: c: d.
Я надеюсь, что сопоставление аргументов взаимодействия следует принципу наименьшего удивления, поскольку оно ведет себя так же, как и тесты на основе ожиданий. Я также надеюсь, что возможность использовать произвольную функцию для проверки обеспечит любую необходимую гибкость. Если вы используете ожидания, попробуйте и дайте мне знать.