【问题标题】:Using controller create action in Factory Bot在 Factory Bot 中使用控制器创建操作
【发布时间】:2018-03-21 17:41:01
【问题描述】:

我的控制器中有一个大而复杂的#create 方法。在创建模型实例时,我还将一个大文件保存到服务器,对其进行大量处理以及其他一些事情。

现在在我的其他测试中,我希望所有这些“副作用”都可用。所以在 Factory Bot 中,仅仅创建一个模型实例是不够的,所以我需要从控制器运行整个 #create 操作。我的问题是:

在工厂文件中运行控制器动作的语法是什么?好像没找到。

这是这种事情的正常做法吗?或者我应该避免依赖控制器的创建操作并在工厂中编写它的最小版本?

谢谢。

【问题讨论】:

    标签: ruby-on-rails rspec factory-bot rspec-rails


    【解决方案1】:

    ...在 Factory Bot 中,仅仅创建一个模型实例是不够的

    Factory Bot 不适用于控制器,因为它只专注于对象。正如 repo 描述的那样,它是“一个用于将 Ruby 对象设置为测试数据的库。”

    现在在我的其他测试中,我希望所有这些“副作用”都可用......我需要从控制器运行整个 #create 操作。

    将 Factory Bot 视为仅用于模拟模型数据以进行测试。你的工厂并不关心你的控制器和视图中有什么。

    如果您想测试控制器操作,您应该查看controller specsrequest specs。 (链接假定使用 rspec。)

    在编写控制器或请求规范时,您可以使用工厂创建一个对象,然后您可以在控制器/请求规范中使用该对象,从而测试您的创建操作对该对象的影响。

    我的控制器中有一个大而复杂的#create 方法。

    如果创建操作时间过长,我还建议您中断创建操作。实现此目的的两种方法是通过controller concernsservice objects。这两种方法也会使测试更容易,因为您可以分别测试每个关注点/服务对象。

    如果任务变得昂贵,您也可以考虑将任务移到后台(或客户端),因为这会阻碍请求并对性能产生负面影响。


    直接回答您的问题:

    在工厂文件中运行控制器动作的语法是什么?

    没有,因为这不是 Factory Bot 的用途。

    这种事情是正常的做法吗?

    没有。

    或者我应该避免依赖控制器的创建操作并在工厂中编写它的最小版本?

    不。但是,如果控制器变得冗长且混乱,请随意在关注点或服务对象之间分解逻辑。

    【讨论】:

    • 您好,感谢您的详细回答。我的问题并不是关于测试控制器动作。它更多地是关于什么是创建模型实例的好方法,它在测试期间有很多副作用。无论如何,您的回答帮助我理顺了一些事情,我发现这超出了 Factory Bot 的意图。实现这一点的最佳方法可能就是在相关测试之前运行创建操作?
    • 是的,我通常会通过浏览器或某种 REST 客户端运行创建操作来开始。
    【解决方案2】:

    经过一番思考并在@seancdavis 的帮助下,我意识到 FactoryBot 不适合触发“创建”操作。相反,我在 before :each 块中运行它,因为这似乎是这样做的方式。

    【讨论】:

      【解决方案3】:

      还有另一种方法可以解决此问题,即利用 FactoryBot 的回调。在我的 users#create 操作中,我自动将用户添加到特定组织,因此我通过向用户工厂添加 after(:create) 块来复制种子数据的这种行为。我还发现我可以通过将 after(:create) 块放在这样的特征中来防止测试套件的其余部分变慢:

      FactoryBot.define do
        factory :user do
          first_name { Faker::Name.unique.first_name }
      
          trait :with_organization do
            after(:create) do |user|
              org = Organization.find_by(name: 'Doctors Without Borders')
              FactoryBot.create(:organization_user, organization: org, user: user)
            end
          end
        end
      end
      

      也许有比这更优雅的解决方案,但到目前为止它已经很好地满足了我的需求。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-22
        • 1970-01-01
        • 1970-01-01
        • 2013-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-06
        相关资源
        最近更新 更多