Phoenix.ConnTest
Исходный кодУдобные средства для тестирования конечных точек Phoenix и вспомогательных функций, связанных с подключениями.
Вероятно, вы захотите использовать этот модуль или включить его в свой ExUnit.CaseTemplate. После использования этот модуль автоматически импортирует все определённые здесь функции, а также функции из Plug.Conn.
Тестирование конечных точек
Phoenix.ConnTest обычно работает с конечными точками. Это предпочтительный способ тестирования всего, что маршрутизатор передаёт для обработки:
@endpoint MyAppWeb.Endpoint test "says welcome on the home page" do conn = get(build_conn(), "/") assert conn.resp_body =~ "Welcome!" end test "logs in" do conn = post(build_conn(), "/login", [username: "john", password: "doe"]) assert conn.resp_body =~ "Logged in!" end
Атрибут модуля @endpoint содержит тестируемую конечную точку, чаще всего саму конечную точку приложения. Если вы используете созданный Phoenix модуль MyApp.ConnCase, это значение задаётся автоматически.
Как и в маршрутизаторе и контроллерах, основная абстракция при тестировании — подключение. build_conn() возвращает новое подключение, а функции этого модуля можно использовать для его изменения перед передачей конечной точке.
Например, можно задать заголовок accepts для запросов JSON следующим образом:
build_conn()
|> put_req_header("accept", "application/json")
|> get("/")
Вы также можете создавать собственные вспомогательные функции, например json_conn(), которая использует build_conn/0 и put_req_header/3, чтобы не повторять настройку подключения во всех тестах.
Тестирование контроллеров
Функции этого модуля также можно использовать для тестирования контроллеров. Хотя тестирование конечных точек предпочтительнее, особенно потому, что контроллер в Phoenix выполняет роль интеграционного слоя между вашей предметной областью и представлениями, в некоторых случаях может быть полезно модульное тестирование контроллеров.
В таких случаях необходимо установить атрибут @endpoint в значение вашего контроллера и передать атом, представляющий действие для вызова:
@endpoint MyAppWeb.HomeController test "says welcome on the home page" do conn = get(build_conn(), :index) assert conn.resp_body =~ "Welcome!" end
Помните, что после установки переменной @endpoint это повлияет на все последующие тесты.
Тестирование представлений
В других случаях вы можете тестировать представление или другой слой, которому для обработки требуется подключение. В таких случаях подключение можно создать с помощью вспомогательной функции build_conn/3:
MyApp.UserView.render("hello.html", conn: build_conn(:get, "/"))
Функция build_conn/0 возвращает подключение без сведений о запросе, а build_conn/3 возвращает подключение, уже заполненное переданными сведениями о запросе.
Повторное использование
Браузеры реализуют хранение данных с помощью файлов cookie. Когда в ответе устанавливается файл cookie, браузер сохраняет его и отправляет в следующем запросе.
Для имитации такого поведения этот модуль предоставляет механизм повторного использования подключений. Функция recycle/1 принимает подключение и возвращает новое, подобное тому, которое возвращает build_conn/0, но все файлы cookie из ответа предыдущего подключения добавлены в качестве заголовков запроса. Это полезно при тестировании нескольких маршрутов, для работы которых требуются файлы cookie или сессия.
Помните, что Phoenix автоматически повторно использует подключение между вызовами. Обычно это работает хорошо, но может привести к потере данных, если вы изменяете подключение перед следующим вызовом:
# No recycling as the connection is fresh
conn = get(build_conn(), "/")
# The connection is recycled, creating a new one behind the scenes
conn = post(conn, "/login")
# We can also recycle manually in case we want custom headers
conn =
conn
|> recycle()
|> put_req_header("x-special", "nice")
# No recycling as we did it explicitly
conn = delete(conn, "/logout")
При повторном использовании также переносятся заголовки "accept" и "authorization", а также сведения о данных узла.
Сводка
- assert_error_sent(status_int_or_atom, func)
Проверяет, что ошибка была обёрнута и отправлена с указанным статусом.
- build_conn()
Создаёт подключение для использования в последующих запросах.
- build_conn(method, path, params_or_body \\ nil)
Создаёт подключение для использования в последующих запросах с предварительно заданными методом, путём и телом запроса.
- bypass_through(conn)
Вызывает конвейеры конечной точки и маршрутизатора.
- bypass_through(conn, router)
Вызывает конвейеры конечной точки и маршрутизатора для текущего маршрута.
- bypass_through(conn, router, pipelines)
Вызывает конвейеры конечной точки и указанные конвейеры маршрутизатора.
- clear_flash(conn)
Очищает хранилище flash-сообщений.
- connect(conn, path_or_action, params_or_body \\ nil)
Передаёт запрос текущей конечной точке.
- delete(conn, path_or_action, params_or_body \\ nil)
Передаёт запрос текущей конечной точке.
- delete_req_cookie(conn, key)
Удаляет файл cookie запроса.
- dispatch(conn, endpoint, method, path_or_action, params_or_body \\ nil)
Передаёт подключение указанной конечной точке.
- ensure_recycled(conn)
Гарантирует повторное использование подключения, если оно ещё не было повторно использовано.
- fetch_flash(conn)
Получает хранилище flash-сообщений.
- get(conn, path_or_action, params_or_body \\ nil)
Передаёт запрос текущей конечной точке.
- get_flash(conn) устарело
Получает всё хранилище flash-сообщений.
- get_flash(conn, key) устарело
Получает указанное значение из хранилища flash-сообщений.
- head(conn, path_or_action, params_or_body \\ nil)
Передаёт запрос текущей конечной точке.
- html_response(conn, status)
Проверяет указанный код состояния и наличие HTML-ответа, а затем возвращает тело ответа, если оно было установлено или отправлено.
- init_test_session(conn, session)
Инициализирует сессию, предназначенную исключительно для тестирования.
- json_response(conn, status)
Проверяет указанный код состояния и наличие ответа JSON, а затем возвращает декодированный ответ JSON, если он был установлен или отправлен.
- options(conn, path_or_action, params_or_body \\ nil)
Передаёт запрос текущей конечной точке.
- patch(conn, path_or_action, params_or_body \\ nil)
Передаёт запрос текущей конечной точке.
- path_params(conn, to)
Возвращает параметры URL, сопоставленные маршрутизатором
%Plug.Conn{}.- post(conn, path_or_action, params_or_body \\ nil)
Передаёт запрос текущей конечной точке.
- put(conn, path_or_action, params_or_body \\ nil)
Передаёт запрос текущей конечной точке.
- put_flash(conn, key, value)
Помещает указанное значение под заданным ключом в хранилище flash-сообщений.
- put_req_cookie(conn, key, value)
Добавляет файл cookie запроса.
- recycle(conn, headers \\ ~w(accept accept-language authorization))
Повторно использует подключение.
- redirected_params(conn, status \\ 302)
Возвращает параметры, сопоставленные URL, на который было перенаправлено подключение.
- redirected_to(conn, status \\ 302)
Возвращает заголовок location из указанного ответа с перенаправлением.
- response(conn, given)
Проверяет указанный код состояния и возвращает тело ответа, если оно было установлено или отправлено.
- response_content_type(conn, format)
Возвращает тип содержимого, если он соответствует указанному формату.
- text_response(conn, status)
Проверяет указанный код состояния и наличие текстового ответа, а затем возвращает тело ответа, если оно было установлено или отправлено.
- trace(conn, path_or_action, params_or_body \\ nil)
Передаёт запрос текущей конечной точке.
Функции
Функции
assert_error_sent(status_int_or_atom, func)Источник
@spec assert_error_sent(integer() | atom(), function()) :: {integer(), list(), term()} Проверяет, что ошибка была обёрнута и отправлена с указанным статусом.
Полезно для тестирования действий, в которых, как вы ожидаете, возникает ошибка, а ответ оборачивается в HTTP-статус; содержимое обычно отображается представлением MyAppWeb.ErrorHTML.
Функция принимает статус в виде целочисленного HTTP-статуса или атома, например 500 или :internal_server_error. Список допустимых атомов доступен в Plug.Conn.Status. Если возникает ошибка, возвращается 3-кортеж обёрнутого ответа, соответствующий статусу, заголовкам и телу ответа:
{500, [{"content-type", "text/html"} | _], "Internal Server Error"}
Примеры
assert_error_sent :internal_server_error, fn ->
get(build_conn(), "/broken/route")
end
response = assert_error_sent 500, fn ->
get(build_conn(), "/broken/route")
end
assert {500, [_h | _t], "Internal Server Error"} = response
Это также можно использовать, чтобы проверить, что маршрут завершился ошибкой, которая была преобразована в конкретный ответ протоколом Plug.Status, например Ecto.NoResultsError:
assert_error_sent :not_found, fn -> get(build_conn(), "/something-that-raises-no-results-error") end
Примечание: для маршрутов, которые не вызывают ошибку, а возвращают статус, следует напрямую проверять ответ:
conn = get(build_conn(), "/users/not-found") assert response(conn, 404)
build_conn()Источник
@spec build_conn() :: Plug.Conn.t()
Создаёт соединение для использования в последующих запросах.
build_conn(method, path, params_or_body \\ nil)Источник
@spec build_conn(atom() | binary(), binary(), binary() | list() | map() | nil) :: Plug.Conn.t()
Создаёт соединение с заранее заданными методом, путём и телом для использования в последующих запросах.
Это полезно, когда для тестирования Plug или определённой функции требуется конкретное соединение.
bypass_through(conn)Источник
@spec bypass_through(Plug.Conn.t()) :: Plug.Conn.t()
Вызывает конвейеры Endpoint и Router.
Полезно для модульного тестирования Plug, когда для правильной настройки необходимы плаги конвейера Endpoint и/или маршрутизатора.
Обратите внимание на использование get("/") после bypass_through в приведённых ниже примерах. Чтобы выполнить конвейеры плагов, необходимо отправить запрос маршрутизатору. Чаще всего достаточно отправить GET-запрос к корневому пути, но можно указать другой метод или путь, для которых будут выполняться конвейеры.
Примеры
Например, представьте, что вы отдельно тестируете плаг аутентификации, но вам нужно вызвать плаги Endpoint и конвейеры маршрутизатора, чтобы настроить зависимости, связанные с сессией и flash-сообщениями. Один из вариантов — вызвать существующий маршрут, в котором используются нужные конвейеры. Для этого передайте соединение и имя маршрутизатора в bypass_through:
conn =
conn
|> bypass_through(MyAppWeb.Router)
|> get("/some_url")
|> MyApp.RequireAuthentication.call([])
assert conn.halted
Также можно указать, какие конвейеры следует запустить:
conn =
conn
|> bypass_through(MyAppWeb.Router, [:browser])
|> get("/")
|> MyApp.RequireAuthentication.call([])
assert conn.halted
Кроме того, можно вызвать только плаги Endpoint:
conn =
conn
|> bypass_through()
|> get("/")
|> MyApp.RequireAuthentication.call([])
assert conn.halted bypass_through(conn, router)Источник
@spec bypass_through(Plug.Conn.t(), module()) :: Plug.Conn.t()
Вызывает конвейеры Endpoint и Router для текущего маршрута.
См. bypass_through/1.
bypass_through(conn, router, pipelines)Источник
@spec bypass_through(Plug.Conn.t(), module(), atom() | list()) :: Plug.Conn.t()
Вызывает Endpoint и указанные конвейеры Router.
См. bypass_through/1.
clear_flash(conn)Источник
@spec clear_flash(Plug.Conn.t()) :: Plug.Conn.t()
Очищает хранилище flash-сообщений.
connect(conn, path_or_action, params_or_body \\ nil)Источник
Отправляет запрос текущему endpoint.
Подробнее см. dispatch/5.
delete(conn, path_or_action, params_or_body \\ nil)Источник
Отправляет запрос текущему endpoint.
Подробнее см. dispatch/5.
delete_req_cookie(conn, key)Источник
@spec delete_req_cookie(Plug.Conn.t(), binary()) :: Plug.Conn.t()
Удаляет cookie запроса.
dispatch(conn, endpoint, method, path_or_action, params_or_body \\ nil)Источник
Отправляет соединение указанному endpoint.
При вызове через get/3, post/3 и аналогичные функции endpoint автоматически извлекается из атрибута модуля @endpoint; в противном случае его необходимо передать в качестве аргумента.
Соединение будет настроено с указанными method, path_or_action и params_or_body.
Если path_or_action — строка, она считается путём запроса и сохраняется в соединении как таковой. Если это атом, предполагается, что он обозначает действие, и соединение отправляется указанному действию.
Параметры и тело
Эта функция, а также get/3, post/3 и аналогичные функции принимают тело запроса или параметры в качестве последнего аргумента:
get(build_conn(), "/", some: "param") get(build_conn(), "/", "some=param&url=encoded")
Допустимые значения:
nil— означает, что тело отсутствуетбинарная строка — содержит тело запроса. В таких случаях в качестве параметра необходимо указать
:headersс типом содержимогокарта или список — содержит параметры, которые автоматически задают тип содержимого multipart. Карта или список могут содержать другие списки или карты; ключи всех записей будут преобразованы в строки
структура — в отличие от других карт, структура передаётся без изменений, без преобразования её записей
ensure_recycled(conn)Источник
@spec ensure_recycled(Plug.Conn.t()) :: Plug.Conn.t()
Проверяет, что соединение было повторно использовано, и при необходимости выполняет его повторное использование.
Подробнее см. recycle/1.
fetch_flash(conn)Источник
@spec fetch_flash(Plug.Conn.t()) :: Plug.Conn.t()
Извлекает хранилище flash-сообщений.
get(conn, path_or_action, params_or_body \\ nil)Источник
Отправляет запрос текущему endpoint.
Подробнее см. dispatch/5.
get_flash(conn)Источник
@spec get_flash(Plug.Conn.t()) :: map()
Получает всё хранилище flash-сообщений.
get_flash(conn, key)Источник
@spec get_flash(Plug.Conn.t(), term()) :: term()
Получает указанное значение по ключу из хранилища flash-сообщений.
head(conn, path_or_action, params_or_body \\ nil)Источник
Отправляет запрос текущему endpoint.
Подробнее см. dispatch/5.
html_response(conn, status)Источник
@spec html_response(Plug.Conn.t(), status :: integer() | atom()) :: String.t()
Проверяет указанный код состояния, наличие HTML-ответа и возвращает тело ответа, если оно было задано или отправлено.
Примеры
assert html_response(conn, 200) =~ "<html>"
init_test_session(conn, session)Источник
@spec init_test_session(Plug.Conn.t(), map() | keyword()) :: Plug.Conn.t()
Инициализирует сессию, предназначенную исключительно для тестирования.
json_response(conn, status)Источник
@spec json_response(Plug.Conn.t(), status :: integer() | atom()) :: term()
Проверяет указанный код состояния, наличие JSON-ответа и возвращает декодированный JSON-ответ, если он был задан или отправлен.
Примеры
body = json_response(conn, 200) assert "can't be blank" in body["errors"]
options(conn, path_or_action, params_or_body \\ nil)Источник
Отправляет запрос текущему endpoint.
Подробнее см. dispatch/5.
patch(conn, path_or_action, params_or_body \\ nil)Источник
Отправляет запрос текущему endpoint.
Подробнее см. dispatch/5.
path_params(conn, to)Источник
@spec path_params(Plug.Conn.t(), String.t()) :: map()
Возвращает совпавшие параметры URL для маршрутизатора %Plug.Conn{}.
Полезно для извлечения параметров пути из возвращённых URL, например из результатов перенаправления Phoenix.LiveViewTest.
Примеры
assert {:error, {:redirect, %{to: "/posts/123" = to}}} = live(conn, "/path")
assert %{id: "123"} = path_params(conn, to) post(conn, path_or_action, params_or_body \\ nil)Источник
Отправляет запрос текущему endpoint.
Подробнее см. dispatch/5.
put(conn, path_or_action, params_or_body \\ nil)Источник
Отправляет запрос текущему endpoint.
Подробнее см. dispatch/5.
put_flash(conn, key, value)Источник
@spec put_flash(Plug.Conn.t(), term(), term()) :: Plug.Conn.t()
Помещает указанное значение в хранилище flash-сообщений под заданным ключом.
put_req_cookie(conn, key, value)Источник
@spec put_req_cookie(Plug.Conn.t(), binary(), binary()) :: Plug.Conn.t()
Добавляет cookie запроса.
recycle(conn, headers \\ ~w(accept accept-language authorization))Источник
@spec recycle(Plug.Conn.t(), [String.t()]) :: Plug.Conn.t()
Повторно использует соединение.
Повторное использование принимает соединение и возвращает новое соединение, содержащее cookie и соответствующую информацию из исходного.
Это имитирует поведение браузеров, при котором cookie, возвращённые в ответе, доступны в последующих запросах.
По умолчанию повторно используются только заголовки "accept", "accept-language" и "authorization". Однако можно задать собственный набор заголовков, передав вторым аргументом функции список строк с их именами.
Обратите внимание: recycle/1 вызывается автоматически при отправке запроса endpoint, если соединение ещё не было повторно использовано.
redirected_params(conn, status \\ 302)Источник
@spec redirected_params(Plug.Conn.t(), status :: non_neg_integer()) :: map()
Возвращает совпавшие параметры URL, на который было перенаправлено соединение.
Использует маршрутизатор %Plug.Conn{}, совпавший в предыдущем запросе. Вызывает ошибку, если заголовок location ответа не задан или ответ не соответствует коду состояния перенаправления (по умолчанию 302).
Примеры
assert redirected_to(conn) =~ "/posts/123"
assert %{id: "123"} = redirected_params(conn)
assert %{id: "123"} = redirected_params(conn, 303) redirected_to(conn, status \\ 302)Источник
@spec redirected_to(Plug.Conn.t(), status :: non_neg_integer()) :: String.t()
Возвращает заголовок location из указанного ответа перенаправления.
Вызывает ошибку, если ответ не соответствует коду состояния перенаправления (по умолчанию 302).
Примеры
assert redirected_to(conn) =~ "/foo/bar" assert redirected_to(conn, 301) =~ "/foo/bar" assert redirected_to(conn, :moved_permanently) =~ "/foo/bar"
response(conn, given)Источник
@spec response(Plug.Conn.t(), status :: integer() | atom()) :: binary()
Проверяет указанный код состояния и возвращает тело ответа, если оно было задано или отправлено.
Примеры
conn = get(build_conn(), "/") assert response(conn, 200) =~ "hello world"
response_content_type(conn, format)Источник
@spec response_content_type(Plug.Conn.t(), atom()) :: String.t()
Возвращает тип содержимого, если он соответствует указанному формату.
Примеры
# Assert we have an html response with utf-8 charset assert response_content_type(conn, :html) =~ "charset=utf-8"
text_response(conn, status)Источник
@spec text_response(Plug.Conn.t(), status :: integer() | atom()) :: String.t()
Проверяет указанный код состояния, наличие текстового ответа и возвращает тело ответа, если оно было задано или отправлено.
Примеры
assert text_response(conn, 200) =~ "hello"
trace(conn, path_or_action, params_or_body \\ nil)Источник
Отправляет запрос текущему endpoint.
Подробнее см. dispatch/5.
© 2014 Chris McCord
Licensed under the MIT License.
https://phoenix.hexdocs.pm/Phoenix.ConnTest.html