Elixir:如何在数据库中需要记录时测试Phoenix控制器?有种子还是嘲笑?

Ole*_*ann 4 elixir phoenix-framework

在测试控制器时,在测试数据库中包含一些数据会很有用.有时您可能想要测试数据创建.设置它的正确方法是什么?控制器测试应该测试控制器的create功能是否正常,而不是模型.

作为一个例子,我想测试一个Session控制器,我有两个测试.一个是测试创建的用户是否可以登录.另一个是,如果密码错误,他就不能.两者都依赖于用户在数据库中.我现在如何处理它是首先创建用户:

defmodule MyApp.SessionControllerTest do
  use MyApp.ConnCase

  alias MyApp.Admin
  @valid_attrs %{email: "email@example.com", name: "John Doe", password: "goodpassword", password_confirmation: "goodpassword", password_hash: "somecontent", username: "username"}
  @invalid_attrs %{}

  setup do
    {:ok, conn: put_req_header(conn, "accept", "application/json")}
  end

  test "admin can login after creation" do
    conn = post conn, admin_path(conn, :create), admin: @valid_attrs
    body = json_response(conn, 201)
    assert Repo.get_by(Admin, email: @valid_attrs[:email])
    conn = post conn, session_path(conn, :create), %{data: %{attributes: %{email: @valid_attrs[:email], password: @valid_attrs[:password]}}}
    body = json_response(conn, 201)
    assert body["data"]["token"]
  end

  test "login with wrong password returns an error" do
    conn = post conn, session_path(conn, :create), %{data: %{attributes: %{email: @valid_attrs[:email], password: "wrongpassword"}}}
    body = json_response(conn, 403)
    assert body["error"]
  end

end
Run Code Online (Sandbox Code Playgroud)

如果我现在在我的Admin模型上添加唯一性限制,这可能会变得混乱,因为每当我需要数据库中的用户时,我必须确保测试没有因为这个约束而失败但是因为测试控制器中的某些东西是错误的.此外,还不清楚测试运行的顺序与几次测试中的数据创建保持一致似乎是一场噩梦.

我要么想要一个我在开始时定义创建数据的地方.或者使用模拟进行控制器测试.

这怎么可能?

Fab*_*755 10

使用此setup功能可以向数据库添加一些数据.

setup do
  Repo.insert!(%User{id: 1, password: "somepassword", ....})
  ....
  :ok
end
Run Code Online (Sandbox Code Playgroud)

setup将在每次测试之前调用.有关更多信息,请参阅ExUnit hexdocs.

为了在同步模式下逐步运行测试,请添加async: false以使用调用.

defmodule MyApp.SessionControllerTest do
  use MyApp.ConnCase, async: false`
Run Code Online (Sandbox Code Playgroud)

但我认为最好在不依赖其他测试的情况下运行测试.

defmodule MyApp.SessionControllerTest do
  use MyApp.ConnCase

  alias MyApp.Admin
  @valid_attrs %{email: "email@example.com", name: "John Doe", password: "goodpassword", password_confirmation: "goodpassword", password_hash: "somecontent", username: "username"}
  @invalid_attrs %{}

  setup do
    Repo.insert!(%User{email: "bar@example.com", password: "somepassword", ....})
    {:ok, conn: put_req_header(conn, "accept", "application/json")}
  end

  ...

  test "login with wrong password returns an error" do
    conn = post conn, session_path(conn, :create), %{data: %{attributes: %{email: "bar@example.com", password: "wrongpassword"}}}
    body = json_response(conn, 403)
    assert body["error"]
  end

end
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.

  • 由于他的部分问题是关于测试之间的隔离,因此值得注意的是,Ecto 2(目前处于测试阶段)允许在沙箱环境中进行并发数据库测试. (6认同)