本文介绍了Elixir:当需要在数据库中记录时,如何测试Phoenix Controller?有种子还是假的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在测试控制器时,将一些数据存储在测试数据库中可能会很有用.有时您可能需要测试数据创建.进行此设置的正确方法是什么?控制器测试应测试控制器的create功能是否正常工作,而不是模型.

When testing controllers it can be useful to have some data in the test database. And sometimes you might want to test the data creation. What is the correct way to set this up? A test for controllers should test if the create function of the controller is working, not the model.

作为一个例子,我想测试一个会话控制器,我有两个测试.一种是测试创建的用户可以登录.如果密码错误,他将无法执行.两者都依赖于用户在数据库中.我现在如何处理它是首先创建用户:

As an example I want to test a Session controller and I have two tests. One is testing that a created user can login. The other that he cannot if the password is wrong. Both rely on a user being in the database. How I deal with it now is to create the user first:

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

如果我现在在我的Admin模型上添加唯一性约束,这可能会变得混乱,因为每当我需要数据库中的用户时,我都必须确保测试不会因为该约束而失败,而是因为被测试的控制器是错误的.同样也不清楚测试的执行顺序,以及在多个测试中与数据创建保持一致似乎是一场噩梦.

If I now add a uniqueness restrain on my Admin model this could potentially get messy since whenever I need a user in the database I have to make sure that the test isn't failing because of this constraint but because something in the tested controller is wrong. Also it isn't clear in which order the tests are run and staying consistent with the data creation over several tests seems like a nightmare.

我要么想在开头定义一个地方创建数据.或使用模拟程序进行Controller测试.

I either want one place where I define in the beginning which Data is created. Or use mocks for Controller testing.

这怎么可能?

推荐答案

使用setup函数向数据库中添加一些数据.

Use the setup function for add some data to your database.

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

setup将在每次测试前被调用.有关更多信息,请参见 ExUnit十六进制文档.

The setup will be called before every test.See ExUnit hexdocs for more information.

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

For run the tests step by step in synchronous mode add async: false to use call.

defmodule MyApp.SessionControllerTest do
  use MyApp.ConnCase, async: false`

但是我认为最好运行测试而不依赖其他测试.

But I think it's better to run the tests without dependencies to other tests.

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

希望有帮助.

这篇关于Elixir:当需要在数据库中记录时,如何测试Phoenix Controller?有种子还是假的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 04:12