1

我想为sti子类上的方法构建一个rspec测试,测试只读取父模型的方法。该方法在应用程序中工作,而不是在rspec测试中。我想不出什么我失踪rspec测试子类sti方法rails 4

模型/动物/ 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)>' 

UPDATE

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(CatMa mmalAnimal)

,并得到这个错误

1)MammalAnimal.favorite和.favorite表示最喜欢的猫 故障/错误:期待(cat_animal_mammal.class.constantize)。为了EQ(CatMammalAnimal)

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

你的对象,当您添加预期(cat_mammal_animal.class.constantize)。为了EQ(CatMammalAnimal会发生什么)到你期望的失败线以上?你也可以发布你的工厂? –

+0

我已经更新了它,但我不确定你想要用新的线测试。 – NothingToSeeHere

+0

哎呀,我猜的是constantize位。我的理论是,你的工厂以某种方式创建了正确类型的对象,但错误的类。你可以将常量部分取出并使CatMammalAnimal成为一个字符串。 –

回答

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) 
+0

我不知道为什么这个工作,但它确实。 – NothingToSeeHere