2016-03-22 10 views
0

Ich weiß, einige von euch schon mit diesem meinem Verstand zweifeln. Ich habe eine Klasse ActiveRecord, die Methode verwendet, um in einem JSON-Attribut zu graben, das es hat.Rails/Rspec respond_to eine method_missing Lookup

# app/models/request_interactor.rb 

    ... 

    def method_missing(method_sym, *arguments, &block) 
    return self.request_params[method_sym.to_s] if self.request_params[method_sym.to_s] 
    super 
    end 

der Test wie folgt aussieht

before(:each) do 
    @ri = RequestInteractor.create(result: {magic_school: true, magic_learnt: 'all things magical'}, request_params: {application_id: 34, school_id: 20, school_name: 'Hogwarts', course_name: 'Defence against the Dark Arts.'}) 
end 

it 'should respond to attributes set in the request parameters' do 
    expect(@ri).to respond_to(:school_name) 
    expect(@ri.school_name).to eq('Hogwarts') 
end 

Ich habe versucht, innerhalb der Test Bindung wird die @ri.school_name'Hogwarts' eq, aber wenn es die responds_to läuft wird es scheitern zu sagen gibt es kein solches Verfahren! Der dreckige, dreckige Lügner!

Ich habe versucht, so etwas wie dies in dem Modell zu tun:

def respond_to?(method, include_private = false) 
    super || self.respond_to?(method, include_private) 
end 

Aber das wird eine Stack-Ebene zu tief, weil die Rekursion, wegen Rekursion zurückkehren .. so jetzt das Schicksal meines Tages ist in Ihrem Hände! Erleuchte mich, meine Großartigen. Wie würde ich die Antwort auf die fehlende Methode testen?

Antwort

2

Verwendung respond_to_missing. Mehr Infos here. Jetzt

, mit all dies gesagt ist. Ihr Muster wird immer noch häschen aussehen, wenn Sie mich fragen.

refactors

Ruby hat Tonnen Weg, dies zu reinigen.

  1. eine Delegation Muster verwenden

    delegate :method_name, :to => :request_params

    (andere Optionen in doc überprüfen). Dies sollte Ihre Probleme lösen, indem ein Verfahren in Ihrem Objekt mit so respond_to? arbeiten und Sie werden überwiegende method_missing vermeiden.

  2. Generieren Sie Ihre Zugriffsmethoden, wenn request_params (Meta-Programmierung Ihrer Accessoren) einstellen.

  3. Verwenden Sie OpenStruct, da diese mit einem Hash wie Ihrem request_params initialisiert werden können. Wenn Sie eine Delegation hinzufügen, sollten Sie cool sein.

Hoffe, das hilft.

+0

Hey @muichkine Vielen Dank für Ihre Anregungen, habe ich nicht über die Delegation Muster verwenden, ich mag es wirklich! Die einzige Reservierung, die ich verwende, ist, dass das 'request_params' ein JSON-Objekt ist, so dass es darauf zugreifen muss, als wäre es ein Hash. Also vielleicht verlassen Methode fehlt und dann mit dem Delegiertenmuster einen Haken für die Antwort zu bieten. Die Request-Parameter werden dem Objekt schon früh zugewiesen und das RI-Objekt wird erst viel später gespeichert. Daher müsste ich einen "before_save" -Filter verwenden, um die Accessoren zu metatieren. Lass mich das Delegationsmuster versuchen, es sieht am besten aus :) TY – TheLegend