2017-08-05 31 views
1

我正在使用最新版本的Solidus電子商務(Spree的分叉),我遇到此問題。要快速形容它:Solidus:在after_save回調中執行的代碼返回rspec中的錯誤

  1. 在聯繫我在施普雷創建施普雷::會員記錄
  2. after_save的回調::成員創造產品和2個變種

當我運行的服務器此代碼的工作,但是,當我試圖使用Rspec的它給我這個錯誤:

Failure/Error: reload.product.setup_membership_variants 

NoMethodError: 
    undefined method `setup_membership_variants' for nil:NilClass 
# ./app/models/spree/membership.rb:26:in `block in setup_product' 
# ./app/models/spree/membership.rb:18:in `setup_product' 
# /box/gems/factory_girl-4.8.0/lib/factory_girl/configuration.rb:18:in `block in initialize' 
# /box/gems/factory_girl-4.8.0/lib/factory_girl/evaluation.rb:15:in `create' 
# /box/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:12:in `block in result' 
# /box/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:9:in `tap' 
# /box/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:9:in `result' 
# /box/gems/factory_girl-4.8.0/lib/factory_girl/factory.rb:42:in `run' 
# /box/gems/factory_girl-4.8.0/lib/factory_girl/factory_runner.rb:29:in `block in run' 
# /box/gems/factory_girl-4.8.0/lib/factory_girl/factory_runner.rb:28:in `run' 
# /box/gems/factory_girl-4.8.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method' 
# ./spec/controllers/spree/premium_controller_spec.rb:4:in `block (2 levels) in <top (required)>' 
# ./spec/controllers/spree/premium_controller_spec.rb:33:in `block (6 levels) in <top (required)>' 
# ./spec/controllers/spree/premium_controller_spec.rb:53:in `block (8 levels) in <top (required)>' 
# ./spec/controllers/spree/premium_controller_spec.rb:53:in `block (7 levels) in <top (required)>' 

這裏是我使用的代碼:

membership.rb

class Spree::Membership < Spree::Base 

    has_many :active_memberships, class_name: 'Spree::ActiveMembership', dependent: :destroy 

    has_one :membership_product, class_name: "Spree::MembershipProduct", dependent: :destroy 
    has_one :product, through: :membership_product, source: :product 

    validates :name, presence: true 
    validates :monthly_quota, presence: true 
    validates :price, presence: true 

    after_save :setup_product 

    private 

    def setup_product 
    if product.nil? 
     ActiveRecord::Base.transaction do 
     create_membership_product(
      product: Spree::Product.create(
      name: name, 
      price: price, 
      shipping_category: Spree::ShippingCategory.find_by(name: "Default") 
     ) 
     ) 
     reload.product.setup_membership_variants 
     end 
    else 
     product.update(name: name, price: price) 
    end 
    end 

end 

product_decorator.rb

Spree::Product.class_eval do 
    def setup_membership_variants 
    ot = Spree::OptionType.find_or_create_by(name: "Membership") 
    option_types << ot 

    if ot.option_values.empty? 
     ["Monthly", "Yearly"].each do |freq| 
     ot.option_values.create(name: freq, presentation: freq) 
     end 
    end 


    month = variants.create(is_master: false, price: price, track_inventory: false) 
    month.option_values << Spree::OptionValue.find_by(name: "Monthly") 
    year = variants.create(is_master: false, price: price * 12, track_inventory: false) 
year.option_values << Spree::OptionValue.find_by(name: "Yearly") 
    end 
end 

membership.rb factory

FactoryGirl.define do 
    factory :membership, class: Spree::Membership do 
    name {FFaker::Lorem.word} 
    monthly_quota { rand(10..200) } 
    price { rand(10..200) } 

    trait :unnamed do 
     name nil 
    end 

    trait :without_quota do 
     monthly_quota nil 
    end 

    trait :priceless do 
     price nil 
    end 
    end 
end 

example of controller test

require 'rails_helper' 

RSpec.describe Spree::PremiumController, type: :controller do 
    let(:valid_membership) { create(:membership) } 
    let(:variant) { create(:master_variant) } 

    context "#show" do 
    it "returns http success" do 
     get :show 
     expect(response).to have_http_status(:success) 
    end 
    it "returns all memberships" do 
     get :show 
     expect(assigns[:memberships]).to include(valid_membership) 
    end 
    end 

    context "#create" do 
    let!(:store) { create(:store) } 

    context "user not logged" do 

     context "valid attributes" do 
     context "user doesn't exist in database" do 
      subject do 
      post(:create, params: { 
       premium: { 
       first_name: "Ondrej", 
       last_name: "Kubala", 
       email: "[email protected]", 
       password: "test123", 
       password_confirmation: "test123", 
       membership_id: valid_membership.id, 
       payment_frequency: "1", #monthly yearly is 2 
       cc_number: "4111111111111111", 
       cc_exp_date: "10/22", 
       cvv: "123" 
       } 
      }) 
      end 

      it "creates user with valid attributes" do 
      expect { subject }.to change { Spree::User.count }.from(0).to(1) 
      end 

      it "logs in user" do 
      expect(controller.warden).to receive(:set_user) 
      subject 
      end 

      context "create order with variant" do 
      it "should handle population" do 
       expect { subject }.to change { Spree::Order.count }.by(1) 
       user = Spree::User.find_by email: "[email protected]" 

       order = user.orders.last 
       expect(response).to redirect_to go_premium_path 

       expect(order.line_items.size).to eq(1) 
       # line_item = order.line_items.first 
       # expect(line_item.variant_id).to eq(valid_membership.reload.product.variants.) 
      end 
      it "charges credit card" 
      it "should redirect to account page" 
      end 
     end 

     context "user already exists" 
     end 

     context "wrong user attributes" do 

     end 

     context "wrong payment attributes" do 

     end 
    end 

    context "user is logged in" do 
     let(:user) { create(:user) } 

     before do 
     allow(controller).to receive_messages try_spree_current_user: user 
     allow(controller).to receive_messages spree_current_user: user 
     end 

     it "doesn't create user" 
    end 
    end 
end 

我沒有在Rspec的太多的經驗,但它的怪異,它當服務器在運行,開發工作,但在測試中它給了我那個錯誤。

任何想法是什麼錯?

回答

0

我的猜測是產品創建調用失敗,出於某種原因。 嘗試使用爆炸版本(product: Spree::Product.create!)以在發生錯誤時拋出錯誤。

如果產品確實被創建,請使用prybyebug來找出爲什麼在reload成員資格後,產品與membership沒有關聯。

相關問題