2014-04-18 13 views
7

Ho cercato molto e non riesco a capirlo anche se sembra semplice. Ecco un esempio semplificato di ciò che voglio fare.Rspec 3.0 Come simulare un metodo che sostituisce il parametro ma senza alcun valore di ritorno?

Creare un metodo semplice che fa qualcosa, ma non restituisce nulla, come ad esempio:

class Test 
    def test_method(param) 
    puts param 
    end 
    test_method("hello") 
end 

Ma nel mio test RSpec ho bisogno di passare un parametro diverso, come ad esempio "arrivederci" al posto di "ciao ". So che questo ha a che fare con stub e deride, e ho guardando oltre la documentazione, ma non riesco a capirlo: https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/method-stubs

Se lo faccio:

@test = Test.new 
allow(@test).to_receive(:test_method).with("goodbye") 

mi dice di spegnere un valore predefinito ma non riesco a capire come farlo correttamente.

Messaggio di errore:

received :test_method with unexpected arguments 
    expected: ("hello") 
    got: ("goodbye") 
Please stub a default value first if message might be received with other args as well.  

Sto usando RSpec 3.0, e chiamando qualcosa come

@test.stub(:test_method) 

non è permesso.

+0

Il tuo messaggio di errore sembra essere il contrario del tuo stub. –

risposta

1

Per esempio, dal momento che non è necessario per testare il risultato effettivo di test_method, ma solo che puts viene chiamato in esso passando param, vorrei solo prova impostando l'attesa e di eseguire il metodo:

class Test 
    def test_method(param) 
    puts param 
    end 
end 

describe Test do 
    let(:test) { Test.new } 

    it 'says hello via expectation' do 
    expect(test).to receive(:puts).with('hello') 
    test.test_method('hello') 
    end 

    it 'says goodbye via expectation' do 
    expect(test).to receive(:puts).with('goodbye') 
    test.test_method('goodbye') 
    end 
end 

che a quanto pare si sta tentando di fare è impostare un test spy sul metodo, ma poi penso che si sta impostando lo stub un livello troppo alto (su test_method stesso anziché la chiamata a puts all'interno di test_method). Se si mette lo stub sulla chiamata a puts, i test dovrebbero passare:

describe Test do 
    let(:test) { Test.new } 

    it 'says hello using a test spy' do 
    allow(test).to receive(:puts).with('hello') 
    test.test_method('hello') 
    expect(test).to have_received(:puts).with('hello') 
    end 

    it 'says goodbye using a test spy' do 
    allow(test).to receive(:puts).with('goodbye') 
    test.test_method('goodbye') 
    expect(test).to have_received(:puts).with('goodbye') 
    end 
end 
+1

Grazie - questo è utile! Per uno, non sapevo che potevi dire "aspetta (test). Per ricevere (: puts)" - pensavo che si potesse chiamare solo il metodo straight ('test_method' qui), quindi è bene sapere. Alla fine il mio problema reale era più complesso e ho deciso che avevo solo bisogno di cambiare il mio codice per definire il metodo che * ha * restituito un valore, che è probabilmente una pratica migliore comunque. E poi è facile usare 'allow (test). Per ricevere (: test_method) .and_return ('addio')'. Sono sicuro che c'è un altro modo per usarne una parte, ed è anche bello sapere delle spie di test - non l'avevo mai visto prima. – user3060126

4

come impostare un valore di default che si spiega in

and_call_original can configure a default response that can be overriden for specific args

require 'calculator' 

RSpec.describe "and_call_original" do 
    it "can be overriden for specific arguments using #with" do 
    allow(Calculator).to receive(:add).and_call_original 
    allow(Calculator).to receive(:add).with(2, 3).and_return(-5) 

    expect(Calculator.add(2, 2)).to eq(4) 
    expect(Calculator.add(2, 3)).to eq(-5) 
    end 
end 

di origine in cui sono venuto a sapere che può essere trovato a https://makandracards.com/makandra/30543-rspec-only-stub-a-method-when-a-particular-argument-is-passed