Elixir / Phoenix:如何在不使用Ecto的情况下对模型进行单元测试?

时间:2016-04-15 21:37:26

标签: elixir phoenix-framework

我正在使用自定义数据库适配器构建一个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

我该如何处理?

2 个答案:

答案 0 :(得分:5)

简短回答:而不是.createQustion, span { display: block; } .correctAnswer { background-color: green; } .correctChoice { border: 1px solid green; } .incorrectChoice { border: 1px solid red; }只使用<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script type="text/x-handlebars-template" id="appTemplate"> {{#each questions}} {{this.question}} <ul class="questions" id={{this.no}}> {{#each answers}} {{#if this.correct}} <li class='correct'>{{this.text}}</li> {{else}} <li>{{this.text}}</li> {{/if}} {{/each}} </ul> {{/each}} </script> <div id="app"> <div id="questionContainer"> </div> <div class="createQuestion"> <h2> Enter new question: </h2> <p id="questionOption1" class="questionChoice">What Superpower would I have? <span class="correctAnswer">Fly</span> <span>Invisibility</span> <span>Telekenisis</span> <span>Super Strength</span> </p> Now pick your correct answer & click Save <button class="add">Add question</button> </div> </div>

答案很长。使用Ecto创建项目时,您可以在use App.ModelCase中找到三个不同的测试用例模板:

  • channel_case.ex
  • conn_case.ex
  • model_case.ex

Case templates用于定义可在每个使用模板的测试中使用的函数。

例如,use ExUnit.Case为您定义了这个:

test/support

model_case内的所有内容都会在测试用例的开头注入。如果您不使用Ecto,这根本没用。第一行别名repo,下一行导入Ecto模块(你没有)

安装程序功能可确保在事务内部运行测试,这些测试在完成后可以回滚,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 也是特定于Ecto的。这就是当您使用quote do ... end运行时,此模块根本不存在的原因。

所以你有两个选择。您可以使用errors_on这是处理测试的标准方法(您可以通过混合创建非Phoenix应用程序来检查),也可以创建自己的--no-ecto。如果模型测试用例之间有足够的共享代码,这可能是一个好主意。

答案 1 :(得分:1)

使用App.ModelCase选项不会自动生成

--no-ecto

它本身就是use ExUnit.CaseTemplate (See the CaseTemplate docs), 并在使用模块中注入import App.ModelCase。它还会导入一些特定于ecto的模块,但它们对您没用。

在您的情况下,您可以在其中App.ModelCasetest/support/model_case中定义use ExUnit.CaseTemplate,并通过定义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

所以:

  1. 创建文件
  2. 删除与您的应用无关的内容
  3. 添加自己的东西
  4. 或仅use ExUnit.Case代替use App.ModelCase。无论哪种方式都应该有效。

    use ExUnit.Case更简单。 use App.ModelCase将允许您定义所有使用模块中可用的帮助程序。