Pergunta

Eu quero chamar um named_scope que só retornará um registro, mas o named_scope retorna um array, isso não é um grande negócio como eu só posso acorrentar-lo com .primeira:

Model.named_scope(param).first

e isso funciona, o que eu estou lutando com é como stub a chamada encadeada. Alguém tem uma referência ou uma resposta sobre como eu iria sobre a realização isso com Rspec zombaria?

Foi útil?

Solução

Eu descobri algo.

Client.stub!(:named_scope).and_return(@clients = mock([Client]))
@clients.stub!(:first).and_return(@client = mock(Client))

que me permite ligar para o meu controlador:

@client = Client.named_scope(param).first

Ele funciona, mas há uma solução melhor?

EDIT:

O lançamento do rspec 1.2.6 nos permite usar stub_chain o que significa que agora pode ser:

Client.stub_chain(:named_scope, :chained_call).and_return(@clients = [mock(Client)])

Este foi topo da minha cabeça, como sempre verificar a api para fins específicos:)

Outras dicas

Melhor versão do

Client.stub!(:named_scope).and_return(@clients = mock([Client]))
@clients.stub!(:first).and_return(@client = mock(Client))

será:

Client.should_receive(:named_scope).with(param).and_return do
  record = mock_model(Comm)
  record.should_receive(:do_something_else)
  [record]  
end

A questão é bastante antiga e, portanto, há algumas melhorias na forma como arrancar pode ser feito. Agora você pode usar o método stub_chain para stub uma cadeia de chamadas de método. Por exemplo:

@client = Client.named_scope(param).first

pode ser arrancado com:

Client.stub_chain(:named_scope,:first).and_return(@client = mock(Client))

Mais exemplos de stub_chaining:

describe "stubbing a chain of methods" do
  subject { Object.new }

  context "given symbols representing methods" do
    it "returns the correct value" do
      subject.stub_chain(:one, :two, :three).and_return(:four)
      subject.one.two.three.should eq(:four)
    end
  end

  context "given a string of methods separated by dots" do
    it "returns the correct value" do
      subject.stub_chain("one.two.three").and_return(:four)
      subject.one.two.three.should eq(:four)
    end
  end
end

ou por favor dê uma olhada:

Viva o rspecs !!! :)

Acho que isso é em uma especificação controlador?

A sua própria sugestão deve funcionar bem. Outra possibilidade é a de mover a chamada named_scope dentro do seu modelo, para evitar o problema inteiramente. Isso também estar em consonância com os "modelos de gordura, os controladores finas" conselho.

Eu acho que você já tenha feito a coisa controlador fina, colocando a consulta em um escopo nomeado onde ele pode ser reutilizado. Aqui está um código que eu usei antes de eu usar escopos nomeados.

  def mock_comm(stubs={})
    @mock_comm ||= mock_model(Comm, stubs)
  end

  describe "responding to GET index" do

    it "should expose all comms as @comms" do
      Comm.should_receive(:find).with(:all).and_return([mock_comm])
      get :index
      assigns[:comms].should == [mock_comm]
    end
# ...

Eu faria código provavelmente escrita bastante semelhante ao que você já tem, mas talvez colocá-lo em um ajudante que me permite reutilizá-lo. A outra coisa é usar um quadro zombando diferente que talvez lhe dá mais controle. Ter um olhar para railscast Ryan Bates' no RSpec - é um pouco velho agora, mas ainda algumas boas idéias lá

.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top