如何在测试文件中引用外部上下文?

时间:2018-11-13 05:29:03

标签: elixir phoenix-framework

我真的很难理解Phoenix Elixir中的上下文。我有三个上下文,Auth(包含User.ex),GroupsCircle.ex)和ContentShareMark.ex)。在其中的每个模式中,分别存在userscirclessharemarks这些模式。

我试图弄清楚如何在create_circle上下文之外使用预先提供的Groups。有什么类似于Ruby的上下文吗?

content_test.ex中,我正在尝试定义以下内容

@valid_attrs %{circle: Groups.create_circle(%{name: "My test"}), url: "google.com", title: "Google"}

defmodule ShareMark.ContentTest do
  use ShareMark.DataCase

  alias ShareMark.Content
  use ShareMark.Groups
  describe "sharemarks" do
    alias ShareMark.Content.ShareMark
    @valid_attrs %{circle: Groups.create_circle(%{name: "Evan's test"}), url: "google.com", title: "Google"}
    @update_attrs %{circle: Groups.create_circle(%{name: "Mike's test"}), url: "duckduckgo.com", title: "DuckDuckGo"}
    @invalid_attrs %{circle: Groups.create_circle(%{name: "Bad test"})}

    def sharemark_fixture(attrs \\ %{}) do
      {:ok, sharemark} =
        attrs
        |> Enum.into(@valid_attrs)
        |> Content.create_sharemark()

      sharemark
    end
 ...
end

这里是circle.ex

defmodule ShareMark.Groups.Circle do
  use Ecto.Schema
  import Ecto.Changeset

  schema "circles" do
    field :name, :string
    field :creator_id, :id
    many_to_many :members, ShareMark.Auth.User, join_through: "users_circles"
    has_many :sharemarks, ShareMark.Content.ShareMark

    timestamps()
  end

  @doc false
  def changeset(circle, attrs) do
    circle
    |> cast(attrs, [:name])
    |> validate_required([:name])
  end
end

但是它给出了以下错误:

** (CompileError) test/sharemark/content/content_test.exs:8: undefined function create_circle/1

Google完全无济于事,因为Phoenix很少有问题要问。很抱歉遇到这样一个新手问题。

2 个答案:

答案 0 :(得分:2)

在测试中,您有以下一行:

use ShareMark.Groups

这应该是alias声明:

alias ShareMark.Groups

答案 1 :(得分:1)

对于初学者来说,不会强迫您使用 Context ,它们只是更好地组织代码的一种方式。与应用程序的文件类型优先(FTF)结构相比,这使初学者更加困惑,但是从长远来看,它们使代码层次结构更加易于理解和管理。拖拉。

您可以选择使用上下文,也可以将所有模块放在一起。不管哪种方式,您定义的任何公共功能都可以在应用程序的任何其他地方使用(,只要您使用正确的调用它们的模块名称)。

有关上下文的更多资源:


现在您的实际代码,有两个问题

首先,如@Paweł所述,您需要alias您的模块或使用全名:

alias ShareMark.Groups

第二,您正在module attribute Groups.create_circle)中呼叫@value。模块属性与常规的“变量” they are resolved at compile-time不同。意思是说,就您而言,他们将在您甚至开始测试套件之前尝试写入数据库。

要解决此问题,请将初始化逻辑移至实际测试或移至ExUnit的setup/1回调中:

setup do
  %{circle: Groups.create_circle(%{name: "Test Circle"}}
end

test "something", %{circle: circle} do
  valid_attrs = %{circle: circle, url: "google.com", title: "Google"}
  # assert something
end