【问题标题】:Testing an api call with Elixir/Phoenix使用 Elixir/Phoenix 测试 api 调用
【发布时间】:2016-04-23 20:55:29
【问题描述】:

我是 Elixir 和 Phoenix 的新手,我正在尝试创建一个 Web 服务来补充我的网站。首先,我只想通过从 json 文件中导入一些数据来测试我的新数据结构。我想我会通过测试来做到这一点。我已经阅读了基本指南(包括测试部分),但我找不到任何关于测试 api 调用的内容。

从下面的代码中,当我运行mix test 时出现以下错误:

** (ArgumentError) flash not fetched, call fetch_flash/2

这在进行调用并返回连接的线路上失败。我假设我使用了错误的电话/错过了什么?是否有我遗漏的文档,或者有人可以指出一个很好的例子吗?

这是来自我的router.ex 的sn-p:

  scope "/", ContactsApp do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
    resources "/contacts", ContactsController
  end

  # Other scopes may use custom stacks.
  scope "/api", ContactsApp do
    pipe_through :api

    get "/import", ContactsController, :import
  end

目前,我所做的只是复制ContactsController.Create 方法并将其命名为ContactsController.Import。我还复制了“数据有效时创建资源并重定向”测试并使用:import 而不是:create

这是完整的堆栈跟踪:

** (ArgumentError) flash not fetched, call fetch_flash/2
 stacktrace:
   (phoenix) lib/phoenix/controller.ex:997: Phoenix.Controller.get_flash/1
   (phoenix) lib/phoenix/controller.ex:982: Phoenix.Controller.put_flash/3
   (contacts_app) web/controllers/contacts_controller.ex:74: ContactsApp.LogController.stuff/2
   (contacts_app) web/controllers/contacts_controller.ex:1: ContactsApp.LogController.action/2
   (contacts_app) web/controllers/contacts_controller.ex:1: ContactsApp.LogController.phoenix_controller_pipeline/2
   (contacts_app) lib/phoenix/router.ex:261: ContactsApp.Router.dispatch/2
   (contacts_app) web/router.ex:1: ContactsApp.Router.do_call/2
   (contacts_app) lib/contacts_app/endpoint.ex:1: ContactsApp.Endpoint.phoenix_pipeline/1
   (contacts_app) lib/phoenix/endpoint/render_errors.ex:34: ContactsApp.Endpoint.call/2
   (phoenix) lib/phoenix/test/conn_test.ex:194: Phoenix.ConnTest.dispatch/5
   test/controllers/contacts_controller_test.exs:69

【问题讨论】:

  • 您是否在代码或测试中的某处调用get_flash
  • 显然conn = get conn, contacts_path(conn, :import), log: @valid_attrs 确实
  • 你试过mix phoenix.gen.json命令吗?它将为您生成测试。所以你可以看到它是如何完成的。
  • 酷。这有很大帮助。谢谢

标签: testing elixir phoenix-framework


【解决方案1】:

感谢@Dogbert 和@sobolevn,我能够弄清楚我做错了什么。当mix phoenix.gen.html生成代码时,控制器可能有如下内容:

def create(conn, %{"contact" => contact_params}) do
  changeset = Contact.changeset(%Contact{}, contact_params)

  case Repo.insert(changeset) do
    {:ok, _contact} ->
      conn
      |> put_flash(:info, "Contact created successfully.")
      |> redirect(to: contact_path(conn, :index))
    {:error, changeset} ->
      render(conn, "new.html", changeset: changeset)
  end
end

mix phoenix.gen.json生成代码时,控制器包含的代码略有不同:

def create(conn, %{"fred" => fred_params}) do
  changeset = Fred.changeset(%Fred{}, fred_params)

  case Repo.insert(changeset) do
    {:ok, fred} ->
      conn
      |> put_status(:created)
      |> put_resp_header("location", fred_path(conn, :show, fred))
      |> render("show.json", fred: fred)
    {:error, changeset} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(ContactsApp.ChangesetView, "error.json", changeset: changeset)
  end
end

在我复制和粘贴的代码中,@Dogbert 建议调用put_flash(这意味着与:browser 管道一起工作)。使用使用mix phoenix.gen.json 生成的代码可以解决问题。

【讨论】:

    猜你喜欢
    • 2023-03-05
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 2018-04-26
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多