Elixir/Phoenix: 如何在不使用 Ecto 的情况下对模型进行单元测试?
Elixir/Phoenix: How to do unit tests for models without using Ecto?
我正在构建一个 elixir phoenix 应用程序,使用自定义数据库适配器连接到 OrientDB。所以我使用 --no-ecto
选项生成了基本应用程序,因为我没有使用 Ecto。
我正在构建自定义模型和自定义验证,但当然想进行单元测试。
如果我尝试像这样在我的单元测试中包含 ModelCase:
defmodule App.UserTest do
use App.ModelCase
end
我收到错误
module App.ModelCase is not loaded and could not be found
这可能是因为它是 Ecto 的一部分。
如果我不包含它,代码稍后会失败,告诉我
undefined function test/2
我该如何处理?
App.ModelCase
不会使用 --no-ecto
选项自动生成。
它本身 use ExUnit.CaseTemplate
(See the CaseTemplate docs),
并将 import App.ModelCase
注入到 using 模块中。它还导入了一些 ecto 特定的模块,但它们对您没有用。
在你的情况下,你可以在 test/support/model_case
中定义 App.ModelCase
,在其中定义 use ExUnit.CaseTemplate
,并通过定义 using
来定义你想要注入到 using 模块中的内容宏.
只是为了让您了解一些您可能想要做的事情,这里有一个 ecto 特定版本的示例:
defmodule App.ModelCase do
use ExUnit.CaseTemplate
using do
quote do
alias App.Repo
import Ecto
import Ecto.Changeset
import Ecto.Query, only: [from: 1, from: 2]
import App.ModelCase
end
end
setup tags do
# Setup stuff you want to automatically do before tests
end
def some_helper_function
# helper function stuff goes here
#
# this function is available in all using modules because of
# the `import App.ModelCase` in the using macro.
end
end
所以要么:
- 创建文件
- 删除与您的应用无关的内容
- 添加你自己的东西
或者只是 use ExUnit.Case
而不是 use App.ModelCase
。无论哪种方式都应该工作。
use ExUnit.Case
更简单。 use App.ModelCase
将允许您定义在所有使用模块中可用的助手。
简短回答:不用 use App.ModelCase
,只需使用 use ExUnit.Case
。
长答案。使用 Ecto 创建项目时,您会在 test/support
:
中获得三个不同的测试用例模板
- channel_case.ex
- conn_case.ex
- model_case.ex
Case templates 用于定义可在使用模板的每个测试中使用的函数。
例如 model_case
为您定义的是:
using do
quote do
alias App.Repo
import Ecto
import Ecto.Changeset
import Ecto.Query, only: [from: 1, from: 2]
import App.ModelCase
end
end
setup tags do
unless tags[:async] do
Ecto.Adapters.SQL.restart_test_transaction(App.Repo, [])
end
:ok
end
def errors_on(model, data) do
model.__struct__.changeset(model, data).errors
end
quote do ... end
中的所有内容都在测试用例的开头注入。如果您不使用 Ecto,这根本没有用。第一行别名 repo,下一行导入 Ecto 模块(你没有)
设置函数确保测试是 运行 内部事务,可以在完成时回滚并且 errors_on
也是 Ecto 特定的。这就是为什么当你 运行 和 --no-ecto
.
时这个模块根本不存在的原因
所以你有两个选择。您可以只使用 ExUnit.Case
,这是处理测试的标准方式(您可以通过使用 mix 创建非 Phoenix 应用程序来检查),或者您可以创建自己的 App.ModelCase
。如果您的模型测试用例之间有足够的共享代码,这可能是个好主意。
我正在构建一个 elixir phoenix 应用程序,使用自定义数据库适配器连接到 OrientDB。所以我使用 --no-ecto
选项生成了基本应用程序,因为我没有使用 Ecto。
我正在构建自定义模型和自定义验证,但当然想进行单元测试。
如果我尝试像这样在我的单元测试中包含 ModelCase:
defmodule App.UserTest do
use App.ModelCase
end
我收到错误
module App.ModelCase is not loaded and could not be found
这可能是因为它是 Ecto 的一部分。
如果我不包含它,代码稍后会失败,告诉我
undefined function test/2
我该如何处理?
App.ModelCase
不会使用 --no-ecto
选项自动生成。
它本身 use ExUnit.CaseTemplate
(See the CaseTemplate docs),
并将 import App.ModelCase
注入到 using 模块中。它还导入了一些 ecto 特定的模块,但它们对您没有用。
在你的情况下,你可以在 test/support/model_case
中定义 App.ModelCase
,在其中定义 use ExUnit.CaseTemplate
,并通过定义 using
来定义你想要注入到 using 模块中的内容宏.
只是为了让您了解一些您可能想要做的事情,这里有一个 ecto 特定版本的示例:
defmodule App.ModelCase do
use ExUnit.CaseTemplate
using do
quote do
alias App.Repo
import Ecto
import Ecto.Changeset
import Ecto.Query, only: [from: 1, from: 2]
import App.ModelCase
end
end
setup tags do
# Setup stuff you want to automatically do before tests
end
def some_helper_function
# helper function stuff goes here
#
# this function is available in all using modules because of
# the `import App.ModelCase` in the using macro.
end
end
所以要么:
- 创建文件
- 删除与您的应用无关的内容
- 添加你自己的东西
或者只是 use ExUnit.Case
而不是 use App.ModelCase
。无论哪种方式都应该工作。
use ExUnit.Case
更简单。 use App.ModelCase
将允许您定义在所有使用模块中可用的助手。
简短回答:不用 use App.ModelCase
,只需使用 use ExUnit.Case
。
长答案。使用 Ecto 创建项目时,您会在 test/support
:
- channel_case.ex
- conn_case.ex
- model_case.ex
Case templates 用于定义可在使用模板的每个测试中使用的函数。
例如 model_case
为您定义的是:
using do
quote do
alias App.Repo
import Ecto
import Ecto.Changeset
import Ecto.Query, only: [from: 1, from: 2]
import App.ModelCase
end
end
setup tags do
unless tags[:async] do
Ecto.Adapters.SQL.restart_test_transaction(App.Repo, [])
end
:ok
end
def errors_on(model, data) do
model.__struct__.changeset(model, data).errors
end
quote do ... end
中的所有内容都在测试用例的开头注入。如果您不使用 Ecto,这根本没有用。第一行别名 repo,下一行导入 Ecto 模块(你没有)
设置函数确保测试是 运行 内部事务,可以在完成时回滚并且 errors_on
也是 Ecto 特定的。这就是为什么当你 运行 和 --no-ecto
.
所以你有两个选择。您可以只使用 ExUnit.Case
,这是处理测试的标准方式(您可以通过使用 mix 创建非 Phoenix 应用程序来检查),或者您可以创建自己的 App.ModelCase
。如果您的模型测试用例之间有足够的共享代码,这可能是个好主意。