Uma das maneiras de fazer o mock de um object é utilizando o método allow do RSpec.
object = double allow(object).to receive(:foo).and_return(11) expect(object.foo).to be == 11
E quando sabemos que o método foo irá ser chamado múltiplas vezes (dentro de um loop por exemplo) e que o valor deve variar, como podemos fazer o mock disso?
O método and_return pode receber infinitos parâmetros, portanto podemos utilizar disso para retornar múltiplos resultados diferentes:
object = double allow(object).to receive(:foo).and_return(11, 12) expect(object.foo).to be == 11 # First call expect(object.foo).to be == 12 # Second call expect(object.foo).to be == 12 # Third call expect(object.foo).to be == 12 # Fourth call
Note o seguinte, no and_return passamos apenas dois valores que devem ser retornados quando o object chamar o método foo. Isso significa o seguinte, quando o método foo for chamado a primeira vez, ele deverá retornar o valor 11. Quando for chamado da segunda vez em diante ele deverá retornar o valor 12, isso porque a partir da terceira chamada ele vai pegar o último valor adicionado como retorno do objeto mock.
Caso você precise fazer retorno múltiplo para chamadas de um mesmo método para diferentes parâmetros, o and_return com vários valores não será o suficiente, será necessário aplicar múltiplos allow:
object = double
allow(object).to receive(:buzz)
.with('argument')
.and_return(11, 12)
allow(object).to receive(:buzz)
.with('argument_2')
.and_return(13, 14)
# First call with 'argument'
expect(object.buzz('argument')).to be == 11
# Second call with 'argument'
expect(object.buzz('argument')).to be == 12
# Third call with 'argument'
expect(object.buzz('argument')).to be == 12
# First call with 'argument_2'
expect(object.buzz('argument_2')).to be == 13
# Second call with 'argument_2'
expect(object.buzz('argument_2')).to be == 14
# Third call with 'argument_2'
expect(object.buzz('argument_2')).to be == 14Obrigado.
Referências
1. Relishapp Doc - returning a value
2. Makandracards - rspec expecting multiple calls of the same method