2016-09-29 2 views
-1

Ich habe ein Problem, gegen das ich mich seit Stunden den Kopf geschlagen habe, und weder ich noch jemand, den ich gefragt habe, ist gekommen mit einer passenden Antwort.Wie man eine Klassenmethode testet, die ein Attribut einer anderen Klasse in einer containerisierten Weise ändert rspec

Im Wesentlichen schreibe ich eine Methode, mit der ich eine Instanzvariable einer anderen Methode bearbeiten kann. Ich habe mehrere Möglichkeiten, dies zu tun, aber mein Problem besteht darin, den Test für diese Methode zu schreiben. Ich habe viele verschiedene Doppeltypen ausprobiert, aber da sie unveränderlich sind und keine Zustände speichern, habe ich keinen Weg gefunden, es zum Laufen zu bringen. Hier

ist die Klasse, deren working Variable geändert wird:

class MyClass 
    attr_writer :working 

    def working? 
    @working 
    end 
end 

Hier ist die Klasse und Methode, die es zu ändern:

class OtherClass 
    def makes_work 
    @ary_of_instances_of_MyClass_to_fix.map do |x| 
     x.working = true 
     @ary_of_fixed_objects << x 
    end 
    end 
end 

(Die eigentliche Klasse ist viel größer, aber ich habe nur eine verallgemeinerte Version der fraglichen Methode enthalten.Ich kann den ganzen spezifischen Code in einen Kern setzen, wenn es helfen würde)

So brauche ich eine Möglichkeit, daszu testenakzeptiert tatsächlich das Array der zu ändernden Objekte, ändert sie und fügt sie an array_of_fixed_objects an. Was wäre der beste Weg, dies auf containerisierte Weise zu testen, ohne MyClass zu benötigen?

Mein letzter Versuch war Spione zu verwenden, um zu sehen, welche Methoden an meiner Dummy-Instanz aufgerufen wurden, jedoch eine Reihe von Fehlern, je nachdem, was ich getan habe. Hier ist der jüngste Test, den ich schrieb:

describe '#make_work' do 
    it 'returns array of working instances' do 
    test_obj = spy('test_obj') 
    subject.ary_of_instances_of_MyClass_to_fix = [test_obj] 
    subject.makes_work 
    expect(test_obj).to have_received(working = true) 
    end 
end 

Das zur Zeit den Fehler wirft:

undefined method to_sym for true:TrueClass 

Vielen Dank für jede Hilfe! Ich entschuldige mich, wenn einige Formatierungen/Informationen ein wenig durcheinander sind, ich bin immer noch ziemlich neu bei dieser ganzen Stackoverflow-Sache!

Antwort

1

denke ich, das Problem have_received(working = true) ist, sollte es have_received(:working=).with(true)

bearbeiten sein:

Beispiele für die Verwendung have_received


Dies funktioniert für mich

class MyClass 
    attr_writer :working 

    def working? 
    @working 
    end 
end 

class OtherClass 
    attr_writer :ary_of_instances_of_MyClass_to_fix 

    def initialize 
    @ary_of_fixed_objects = [] 
    end 
    def makes_work 
    @ary_of_instances_of_MyClass_to_fix.map do |x| 
     x.working = true 
     @ary_of_fixed_objects << x 
    end 
    end 
end 

describe '#make_work' do 
    subject { OtherClass.new } 
    it 'returns array of working instances' do 
    test_obj = spy('test_obj') 
    subject.ary_of_instances_of_MyClass_to_fix = [test_obj] 
    subject.makes_work 
    expect(test_obj).to have_received(:working=).with(true) 
    end 
end 
+0

Wow, danke! War das also nur ein Fehler in meinem Gebrauch der Spionagesyntax, oder ist das ein anderer Ansatz zu dem, was ich versuchte? – LMCMLJ

+1

@LMCMLJ Ja, ich denke, es war nur der Fall einer falschen Syntax. Ich habe einige Links zu meiner Antwort hinzugefügt, die die Verwendung von 'have_received' demonstrieren – Rashmirathi

0

Wenn Sie lieber nur stubbing vermeiden würde, Sie eine Instanz von OpenStruct anstelle eines Doppel verwenden:

class OtherClass 
    attr_writer :ary_of_instances_of_MyClass_to_fix 

    def initialize 
    @ary_of_instances_of_MyClass_to_fix, @ary_of_fixed_objects = [], [] 
    end 

    def makes_work 
    @ary_of_instances_of_MyClass_to_fix.map do |x| 
     x.working = true 
     @ary_of_fixed_objects << x 
    end 
    @ary_of_fixed_objects 
    end 
end 

require 'ostruct' 

RSpec.describe "#makes_work" do 
    describe "given an array" do 
    let(:array) { [OpenStruct.new(working: nil)] } 

    subject { OtherClass.new } 

    before do 
     subject.ary_of_instances_of_MyClass_to_fix = array 
    end 

    it "sets the 'working' attribute for each element" do 
     expect(array.map(&:working)).to eq [nil] 
     subject.makes_work 
     expect(array.map(&:working)).to eq [true] 
    end 
    end 
end 
Verwandte Themen