2013-05-29 6 views
6

Ich habe ein Objekt MyObject:Wie stub ich eine Methode einer Instanz nur dann, wenn eine bestimmte Instanzvariable einen Wert hat?

class MyObject 

    def initialize(options = {}) 
    @stat_to_load = options[:stat_to_load] || 'test' 
    end 

    def results 
    [] 
    end 
end 

Ich möchte nur, wenn stat_to_load = "times" die results Methode Stummel. Wie kann ich das machen? Ich habe versucht:

MyObject.any_instance.stubs(:initialize).with({ 
    :stat_to_load => "times" 
}).stubs(:results).returns(["klala"]) 

aber es funktioniert nicht. Irgendeine Idee?

+1

Ich kann ein Missverhältnis zwischen "Ergebnis" und "Ergebnisse" in der Frage sehen. Wahrscheinlich nicht deine Antwort, aber lohnt es sich zu reparieren? –

+0

Oups, Kopieren/Einfügen Fehler – Sebastien

+0

Ich weiß nicht einmal, ob das möglich ist, aber wahrscheinlich ist die richtige Lösung, das Objekt oder die Klasse zu injizieren, dann haben Sie viel mehr Kontrolle darüber. Schwer zu sagen/geben Sie Beispiele, ohne zu sehen, wie dieser Code verwendet wird. –

Antwort

0

Also, ich denke, es gibt wahrscheinlich einen einfacheren Weg zu testen, was Sie versuchen zu testen, aber ohne mehr Kontext weiß ich nicht, was ich empfehlen soll. Doch hier ist ein Proof-of-Concept-Code zu zeigen, dass das, was Sie getan werden kann, tun:

describe "test" do 
    class TestClass 
    attr_accessor :opts 
    def initialize(opts={}) 
     @opts = opts 
    end 

    def bar 
     [] 
    end 
    end 
    let!(:stubbed) do 
    TestClass.new(args).tap{|obj| obj.stub(:bar).and_return("bar")} 
    end 
    let!(:unstubbed) { TestClass.new(args) } 

    before :each do 
    TestClass.stub(:new) do |args| 
     case args 
     when { :foo => "foo" } 
     stubbed 
     else 
     unstubbed 
     end 
    end 
    end 

    subject { TestClass.new(args) } 

    context "special arguments" do 
    let(:args) { { :foo => "foo" } } 
    its(:bar) { should eq "bar" } 
    its(:opts) { should eq({ :foo => "foo" }) } 
    end 

    context "no special arguments" do 
    let(:args) { { :baz => "baz" } } 
    its(:bar) { should eq [] } 
    its(:opts) { should eq({ :baz => "baz" }) } 
    end 

end 

test 
    special arguments 
    bar 
     should == bar 
    opts 
     should == {:foo=>"foo"} 
    no special arguments 
    bar 
     should == [] 
    opts 
     should == {:baz=>"baz"} 

Finished in 0.01117 seconds 
4 examples, 0 failures 

jedoch vielen Einsatz von speziellem Thema, das ich mache/lassen Kontextblöcke hier. Weitere Informationen zu diesem Thema finden Sie unter http://benscheirman.com/2011/05/dry-up-your-rspec-files-with-subject-let-blocks/.

+0

Diese Antwort ist für RSpec nicht Mocha –

0

Versuchen Sie unten aus, sollte dies wie erwartet:

Hier werden wir im Grunde eigentlich stubbing new instance erstellt bekommen und auch results Methode der Instanz Anstoßen, die zurückgegeben zu werden.

options = {:stat_to_load => "times"} 
MyObject.stubs(:new).with(options) 
        .returns(MyObject.new(options).stubs(:results).return(["klala"])) 
0

Sie könnten einfach alten Ruby in Ihrem Test verwenden, um dies zu erreichen.

MyObject.class_eval do 
    alias_method :original_results, :results 
    define_method(:results?) do 
    if stats_to_load == "times" 
     ["klala"] 
    else 
     original_results 
    end 
    end 
end 
Verwandte Themen