【问题标题】:Issue with integration testing web application in umbrella伞中集成测试 Web 应用程序的问题
【发布时间】:2017-04-10 14:19:09
【问题描述】:

我正在开发 phoenix 应用程序。此应用程序是伞形应用程序的一部分。在这个保护伞中,我有一些小型应用程序负责应用程序的不同领域,它们是:

  • phoenix web api(“api”)
  • 核心业务逻辑(“核心”)
  • 用户身份验证(“auth”)
  • 数据库架构(“db”)

“api”依赖于“core”和“auth”,而这两个应用程序依赖于“db”。

只有“db”应用有 ecto repo,所有其他应用都没有。该 repo 由“db”应用程序启动并受到监督。

现在我想在“api”应用程序中测试我的控制器。这就是我遇到 ecto 问题的地方。当我测试一个控制器动作时,这个动作将从“auth”或“core”调用一个函数,它从“db”调用Repo的函数(例如Repo.insert/2)。这导致OwnershipError

** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.458.0>.

When using ownership, you must manage connections in one                         
of the three ways:                                                               

  * By explicitly checking out a connection                                      
  * By explicitly allowing a spawned process                                     
  * By running the pool in shared mode                                           

The first two options require every new process to explicitly                    
check a connection out or be allowed by calling checkout or                      
allow respectively.                                                              

The third option requires a {:shared, pid} mode to be set.                       
If using shared mode in tests, make sure your tests are not                      
async.                                                                           

If you are reading this error, it means you have not done one                    
of the steps above or that the owner process has crashed.                        

See Ecto.Adapters.SQL.Sandbox docs for more information.                         

我现在的问题是我不知道如何使用“api”测试中建议的解决方案修复此错误,因为“api”应用程序不知道“db”应用程序,因此无法进行连接检查。当我在直接依赖于“db”项目的应用程序上遇到此错误时,我能够应用“共享模式”解决方案。

我的问题是如何通过“api”集成测试解决所有权问题。

【问题讨论】:

    标签: elixir phoenix-framework ecto ex-unit


    【解决方案1】:

    以下是在伞模式下运行测试的一些注意事项(如错误消息中所述)

    1. 您的依赖存储库需要“签出”
    2. 您的依赖存储库可能永远不会启动
    3. 您的依赖存储库可能未在“共享”模式下运行

    从那里,您的test_helper.exs 可能看起来像这样(伪代码):

    ExUnit.start
    
    Db.Repo.start_link()
    Core.Repo.start_link()
    Auth.Repo.start_link()
    
    Ecto.Adapters.SQL.Sandbox.checkout(Db.Repo)
    Ecto.Adapters.SQL.Sandbox.checkout(Core.Repo)
    Ecto.Adapters.SQL.Sandbox.checkout(Auth.Repo)
    
    Ecto.Adapters.SQL.Sandbox.mode(Api.Repo, :manual)
    Ecto.Adapters.SQL.Sandbox.mode(Db.Repo, :shared)
    Ecto.Adapters.SQL.Sandbox.mode(Core.Repo, :shared)
    Ecto.Adapters.SQL.Sandbox.mode(Auth.Repo, :shared)
    

    更新:

    不要忘记在mix.exs 中包含 DB 的项目路径

    defp deps do
       [
          ...
          {:db, path: "path/to/db"},
          ...
       ]
    end
    

    【讨论】:

    • 感谢您的回答。对此的一些想法:(1)只有一个回购,即“db”应用程序之一。回购是受监督的,应该在“db”应用程序启动时启动。 (2)当我为“api”编写测试时,“api”应用程序不知道有一个ecto repo,因为“api”对“db”没有直接依赖。这就是为什么我不知道如何在我的“应用程序”测试中签出回购协议的原因。我把这个包括在我的问题中
    • @Thorakas 我的答案仍然有效,测试必须启动其他 otp 应用程序。不确定您是否处于异步模式
    • 这些测试不在异步模式下运行。我还将“api”项目配置为需要启动“core”和“auth”,它们本身需要启动“db”。正如我之前所说,我不知道如何将您的答案应用于我的情况。我无法查看Db.Repo,因为该模块在“api”项目中是未知的。
    • @Thorakas 答案已更新,添加了 Db 的依赖项
    猜你喜欢
    • 2015-12-25
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 2013-10-14
    • 1970-01-01
    • 2022-08-08
    • 1970-01-01
    相关资源
    最近更新 更多