Как ссылаться на внешние контексты в тестовых файлах? - PullRequest
0 голосов
/ 13 ноября 2018

Я действительно изо всех сил пытаюсь понять контексты в эликсире Феникса.У меня есть три контекста: Auth (содержит User.ex), Groups (Circle.ex) и Content (ShareMark.ex).Внутри каждого из них есть схемы users, circles и sharemarks соответственно.

Я пытаюсь выяснить, как использовать предварительно предоставленный 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 совершенно бесполезен, так как у Феникса так мало вопросов об этом.Извините за такой начинающий вопрос.

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Для начала, не заставляет вас использовать Контексты , это всего лишь способ лучше организовать ваш код.Это делает их немного более запутанными для начинающих по сравнению со структурой File-Type First (FTF) приложений, но делает иерархию кода намного проще для понимания и управления вдальний путь.

Вы можете использовать контексты или просто собрать все модули вместе. В любом случае, любые определяемые вами публичные функции доступны из любого места приложения ( до тех пор, покатак как вы используете правильное имя модуля для их вызова ).

Дополнительные ресурсы по контекстам:


Теперь к вашему фактическому коду есть две проблемы с ним.

Сначала как @Павел упомянул, вам нужно alias ваш модуль или использовать полное имя:

alias ShareMark.Groups

Во-вторых, вы звоните Groups.create_circle в атрибуте модуля (@value).Атрибуты модуля не похожи на ваши обычные «переменные», они разрешаются во время компиляции .Это означает, что в вашем случае они попытаются выполнить запись в базу данных еще до того, как вы запустите свой набор тестов.

Чтобы это исправить, либо перенесите логику инициализации в ваш реальный тест, либо в setup/1 в ExUnit. обратный вызов:

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
0 голосов
/ 13 ноября 2018

В вашем тесте у вас есть эта строка:

use ShareMark.Groups

это должен быть оператор alias:

alias ShareMark.Groups
...