代码之家  ›  专栏  ›  技术社区  ›  josegp

如何在Rspec上使用FactoryBot创建实例变量

  •  0
  • josegp  · 技术社区  · 3 年前

    我想在我的产品类的RSpec上测试一个类函数。为了便于阅读,我将保留以下内容:

    class Product < ApplicationRecord
    
      private 
    
      def self.order_list(sort_by)
        if sort_by == 'featured' || sort_by.blank?
          self.order(sales: :desc)
        elsif sort_by == 'name A-Z' 
          self.order(name: :asc)
        elsif sort_by == 'name Z-A'
          self.order(name: :desc)
        elsif sort_by == 'rating 1-5'
          self.order(:rating)
        elsif sort_by == 'rating 5-1'
          self.order(rating: :desc)
          elsif sort_by == 'price low-high'
          self.order(:price)
        elsif sort_by == 'price high-low'
          self.order(price: :desc)
        elsif sort_by == 'date old-new'
          self.order(:updated_at)
        elsif sort_by == 'date new-old' 
          self.order(updated_at: :desc)
        end
      end
    end
    
    

    使用参数调用函数后,根据使用的参数,产品列表将以不同的方式排序,供用户查看。

    我还为产品模型构建了FactoryBot:

    FactoryBot.define do
      factory :product do
        sequence(:name) { |n| "product_test#{n}" }
        description { "Lorem ipsum dolor sit amet" }
        price { rand(2000...10000) }
        association :user, factory: :non_admin_user
        rating { rand(1..5) }
    
        trait :correct_availability do
          availability { 1 }
        end
    
        trait :incorrect_availability do
          availability { 3 }
        end
    
        #Adds a test image for product after being created
    
        after(:create) do |product|
          product.photos.attach(
            io: File.open(Rails.root.join('test', 'fixtures', 'files', 'test.jpg')),
            filename: 'test.jpg',
            content_type: 'image/jpg'
          )
        end
    
        factory :correct_product, traits: [:correct_availability]
        factory :incorrect_product, traits: [:incorrect_availability]
      end
    end
    

    基本上,我们想要调用:correct_产品来创建一个被模型验证接受的产品。

    对于规格:

    describe ".order_list" do
        let!(:first_product) { FactoryBot.create(:correct_product, name: "First Product" , rating: 1) }
        let!(:second_product) { FactoryBot.create(:correct_product, name: "Second Product" , rating: 2) }
        let!(:third_product) { FactoryBot.create(:correct_product, name: "Third Product" , rating: 3) }
    
        it "orders products according to param" do
          ordered_list = Product.order_list('rating 1-5')
          expect(ordered_list.all).to eq[third_product, second_product, first_product]
        end
      end
    

    所以基本上,我的问题是,我如何为3个模拟产品中的每一个创建一个实例变量,这样我就可以按照我希望它们出现的顺序在这里命名它们: expect(ordered_list.all).to eq[third_product, second_product, first_product]

    或者,更好的是,有没有一种方法可以通过循环创建实例变量,并在expect中使用实例变量名?这将使我不必像以前那样在FactoryBot上创建3个不同的变量。

    我在网上搜索了一下 instance_variable_set 在某些情况下使用: Testing Rails with request specs, instance variables and custom primary keys Simple instance_variable_set in RSpec does not work, but why not?

    但这似乎对我不起作用。 你知道我该怎么做吗?谢谢

    0 回复  |  直到 3 年前