lundi 6 juillet 2015

Rails Engine host application classes in RSpec tests

I have a Rails Engine that includes methods that link to some of the host application's classes (I know this type of coupling is bad, but in this case it is unavoidable).

I need to test methods that use the host's classes, but I get a uninitialized constant MyEngine::BaseUser error when trying to double/mock/stub the host's classes (BaseUser or Tutor in this case).

I have had a stab at getting round this problem by creating mock classes, but I think what I've left with is a bad idea and means my tests are less useful (see below).

Any idea what I could do better, or suggestions for a better direction to go in?

As I said above, I got round this (badly) like this:

BaseUser = Class.new do
    attr_accessor :id

    def initialize(id = 1)
        @id = id
    end

    def self.find(id)
        self.new(id)
    end

    def tutor
        Tutor.find(self.id)
    end
end

class Tutor
    attr_accessor :id, :first_name

    def initialize(id = 1)
        @id = id
        @first_name = "Tutor with ID #{id}'s first name"
    end

    def self.find(id)
        self.new(id)
    end
end

it 'returns the hosts first name' do
    allow(MyEngine).to receive_message_chain(:user_class, :constantize) { BaseUser }
    ai = FactoryGirl.create(:availability_interval, host_id: 1)
    expect(ai.host_first_name).to eq BaseUser.find(1).tutor.first_name
end

The method I am testing looks like this:

def host_full_name
    MyEngine.user_class.constantize.find(self.host_id).tutor.full_name
end

(MyEngine.user_class is "BaseUser")

Aucun commentaire:

Enregistrer un commentaire