rspec测试子类sti方法rails 4

时间:2016-07-07 19:43:17

标签: ruby-on-rails ruby-on-rails-4 rspec single-table-inheritance

我正在尝试为sti子类的方法构建一个rspec测试,测试只读取父模型的方法。该方法适用于app,而不是在rspec测试中。我无法弄清楚我错过了什么

模型/只动物/ animal.rb

class Animal < ActiveRecord::Base

  def favorite
    "unicorn"
  end

end

模型/只动物/ mammal_animal.rb

class MammalAnimal < Animal

  def favorite
    "whale"
  end

end

模型/只动物/ cat_mammal_animal.rb

class CatMammalAnimal < MammalAnimal

  def favorite
    "tabby"
  end

end

mammal_animal_spec.rb

require 'rails_helper'

RSpec.describe MammalAnimal, type: :model do

  let(:cat_mammal_animal) {FactoryGirl.create(:cat_factory)}
  subject(:model) { cat_mammal_animal }
  let(:described_class){"MammalAnimal"}

  describe "a Cat" do
    it "should initialize successfully as an instance of the described class" do
      expect(subject).to be_a_kind_of described_class
    end

    it "should have attribute type" do
      expect(subject).to have_attribute :type
    end

    it "has a valid factory" do 
      expect(cat_mammal_animal).to be_valid
    end

    describe ".favorite " do 
      it 'shows the favorite Cat' do
        expect(cat_mammal_animal.type).to eq("CatMammalAnimal")
        expect(cat_mammal_animal.favorite).to include("tabby")
        expect(cat_mammal_animal.favorite).not_to include("whale")
        expect(cat_mammal_animal.favorite).not_to include("unicorn")
        print cat_mammal_animal.favorite
      end
    end
  end
end

错误

Failures:
  1) MammalAnimal.favorite and .favorite shows the favorite Cat
     Failure/Error: expect(cat_mammal_animal.type).to include("tabby")
       expected "unicorn" to include "tabby"
     # ./spec/models/mammal_animal_spec.rb:82:in `block (3 levels) in <top (required)>'

更新

animals.rb

FactoryGirl.define do
  factory :animal do
    type 'Animal'
    name "dragon"


    trait :mammal do
      type 'MammalAnimal'
      name "zebra"
    end

    trait :cat do
      type 'CatMammalAnimal'
      name "calico"
    end

    factory :mammal_factory, traits: [:mammal]
    factory :cat_factory, traits: [:cat]

  end

end

根据建议,我在测试中添加了以下行

期望(cat_mammal_animal.class.constantize).to eq(CatMammalAnimal)

并收到此错误

1)MammalAnimal.favorite和.favorite展示了最喜欢的猫      失败/错误:期望(cat_animal_mammal.class.constantize).to eq(CatMammalAnimal)

 NoMethodError:
   undefined method `constantize' for #<Class:0x007f8ed4b8b0e0>
   Did you mean?  constants

1 个答案:

答案 0 :(得分:1)

我认为不是使用trait来创建子类的对象,而是应该为这些对象设置单独的工厂。

factory :animal do
  name 'dragon'
end

factory :mammal, class: MammalAnimal do
  name 'zebra'
end

factory :cat, class: CatMammalAnimal do
  name 'calico'
end

所有这些都可以在animals.rb

中定义

然后你可以创建像

这样的对象
create(:animal)
create(:mammal)
create(:cat)