Как имитировать вложенное использование сторонних API, связанных с потенциально опасными действиями? - PullRequest
0 голосов
/ 09 мая 2019

У меня есть три службы в приложении Clojure:

  • Service A: взаимодействует со сторонним API, вызывая потенциально опасные и необратимые изменения во внешней службе (не может быть написан мной)
  • Service B: использует Службу A для достижения своих целей
  • Service C: использует Службу B для достижения своих собственных целей

Мне нужно написать интеграционные тесты для Сервиса C, которые не не вызывают у сторонних разработчиков, поскольку они не предоставляют ни набора конечных точек тестирования, ни способа отменить мои изменения.

Я вижу два варианта:

  • Передача вызываемых функций в Службу C, например, как вводить экземпляры служб на языке ООП. Это приводит к значительным дополнительным расходам при использовании службы C.

  • Пересмотр опасных функций в Сервисе A с использованием with-redefs-fn. Это требует знания деталей реализации сервисов, которые я не могу контролировать.

Я немного новичок в тестировании на функциональных языках, поэтому более чем возможно, что я упускаю что-то очевидное.

Ответы [ 3 ]

1 голос
/ 10 мая 2019

Если вы знаете некоторые подробности о реализации сервисов, и они в основном написаны на Java, вы можете использовать proxy для создания альтернативных реализаций классов или интерфейсов, которые вы хотите ограничитьво время испытаний.

Пример будет выглядеть так:

(let [proxy-a (proxy [com.dangerous.ServiceA] []
                (launchMissiles [x y z]
                  (log/info "Phew! we didn't fire a missile during tests!")))

      proxy-b  (proxy [com.example.ServiceB] []
                 (callServiceA [x y z]
                   (.launchMissiles proxy-a x y z)))

      proxy-c (proxy [com.example.ServiceC] [x]
                (callServiceB [x]
                 (.callServiceB proxy-b x 1 2)))]

     ;; Perform a test on the outer proxy with:
     (.callServiceB proxy-c "testing!")

Подробнее здесь: https://clojuredocs.org/clojure.core/proxy

1 голос
/ 10 мая 2019

Если я правильно понимаю ваш сценарий использования, я бы не стал обращаться к Сервису A в моих интеграционных тестах для Сервиса C, посмеявшись над всем Сервисом A с помощью clj-fake-http . Я очень счастливо использовал эту библиотеку в одном из своих рабочих проектов и очень рекомендую ее.

Это предполагает, что Служба А на самом деле является другим процессом, с которым вы разговариваете. Если Служба A работает в том же процессе, что и Служба C, вы могли бы также смоделировать вызовы к стороннему API, который делает Служба A.

0 голосов
/ 10 мая 2019

Используйте опцию № 2, но with-redefs (почти никогда не требуется with-redefs-fn. См.

Пример:


(ns http)

(defn post [url] ; dummy fn for testin
  {:body "Hello world"})

(ns app
  (:require [clojure.test :refer [deftest is run-tests]]))

(deftest is-a-macro
  (with-redefs [http/post (fn [url] {:body "Goodbye world"})]
    (is (= {:body "Goodbye world"} (http/post "http://service.com/greet")))))

(run-tests) ;; test is passing
...