TDD(测试驱动开发)

FactoryGirl

2015-11-22  本文已影响484人  我要走多远

为什么要用factory_girl

在写测试的时候,经常需要构造数据。
而对于我们所要构造的数据:

  1. 除特殊原因,我们需要构建合法的数据
  2. 对于绝大多数测试数据,我们只在乎部分字段(和被测试内容相关的),换句话说,剩下的字段可以是默认的。

而factory girl刚好为解决这些问题提供了一个方便的机制。

factory_girl的使用

  1. 原则
    factory的wiki解释是: factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.
    既一个用来创建对象的地方,而这个地方并不需要我们关注细节。

    在写测试的时候,我们应该尽可能把数据创建,放到factory_girl里面。
    这样做的好处是:
    一,重用。
    二,提供了抽象,让我们更加关注所要进行测试的那一部分,而不是如何构造数据。
    三,便于维护。开发中,数据结构往往是变化的。我们把数据创建放在了一个部分,如果数据结构变化了,需要进行更改,只要改一个地方就好了。

  2. 创建对象
    # 创建对象
    FactoryGirl.define do
    factory :user do
    name "Mike"
    email "user@example.com"
    end
    end
    FactoryGirl.create(:user, name: "New Name")
    # => #<AdminUser: name: "New Name", email: "email "user@example.com")

    # 唯一字段
    factory :user do
      sequence(:email) { |n| "user-#{n}@example.com" }
    end
    
    # 每次产生不一样的字段,假设我们使用了Faker这个gem
    factory :user do
      sequence(:name) { Faker::Name::name }
    end
    
    # 一次创建多个对象
    FactoryGirl.create_list(:user, 2) # 创建两个user
    
  3. 创建带关联的对象

    # 关联
    FactoryGirl.define do
      factory :user do
        email "user@example.com"
      end
    
      factory :post do
        user
      end
    end
    
    # 相当于
    user = User.new
    user.email = "user@example.com"
    user.save!
    post = Post.new
    post.user = user
    post.save!
    
    # 多态
    FactoryGirl.define do
      factory :post do
        association :author, factory: :user
      end
    end
    
    # 一对多
    FactoryGirl.define do
      factory :post do
        name "post-name"
    
        factory :post_with_comments do
          after(:create) do |post, evaluator|
            create_list(:comment, 5, post: post)
          end
        end
      end
    end
    
    # 设置一对多的数量
    FactoryGirl.define do
      factory :post do
        name "post-name"
    
        factory :post_with_comments do
          transient do
            comments_count 5
          end
    
          after(:create) do |post, evaluator|
            create_list(:comment, evaluator.comments_count, post: post)
          end
        end
      end
    end
    create(:post_with_comments, 2) # 有五个comments的post
    create(:post_with_comments, 2) # 有两个comments的post
    
上一篇下一篇

猜你喜欢

热点阅读