Pergunta

pastied as especificações que eu escrevi para a vista posts / show.html.erb em um aplicativo que eu estou escrevendo como um meio para aprender RSpec. Eu ainda estou aprendendo sobre simulações e stubbing. Esta questão é específico para o "deve listar todos os comentários relacionados" spec.

O que eu quero é prova de que a visão show exibe os comentários de um post. Mas o que eu não estou certo sobre é como configurar este teste e, em seguida, fazer o teste iterate através com deve conter declarações ( 'xyz'). Alguma dica? Outras sugestões também são apreciados! Obrigado.

--- Editar

Alguns mais informações. Eu tenho um named_scope aplicado aos comentários na minha opinião (eu sei, eu fiz isso um pouco para trás, neste caso), então @ post.comments.approved_is (verdadeiro). O código pastied responde com o erro "undefined method` approved_is' para #", o que faz sentido desde que eu disse a ele esboço comentários e retornar um comentário. Eu ainda não tenho certeza, no entanto, como a cadeia os topos de modo que post.comments.approved_is @ (true) irá retornar uma matriz de comentários.

Foi útil?

Solução

Stubbing é realmente o caminho a percorrer aqui.

Na minha opinião, todos os objetos em especificações do controlador e vista deve ser arrancado com objetos fictícios. Não há nenhuma necessidade real para passar o tempo de forma redundante testar lógica que já deve ser testado exaustivamente em suas especificações modelo.

Aqui está um exemplo de como eu iria configurar as especificações em seu Pastie ...

describe "posts/show.html.erb" do

  before(:each) do
    assigns[:post] = mock_post
    assigns[:comment] = mock_comment
    mock_post.stub!(:comments).and_return([mock_comment])
  end

  it "should display the title of the requested post" do
    render "posts/show.html.erb"
    response.should contain("This is my title")
  end

  # ...

protected

  def mock_post
    @mock_post ||= mock_model(Post, {
      :title => "This is my title",
      :body => "This is my body",
      :comments => [mock_comment]
      # etc...
    })
  end

  def mock_comment
    @mock_comment ||= mock_model(Comment)
  end

  def mock_new_comment
    @mock_new_comment ||= mock_model(Comment, :null_object => true).as_new_record
  end

end

Outras dicas

Eu não tenho certeza se esta é a melhor solução, mas eu consegui obter a especificação de passar por arrancar apenas o named_scope. Eu apreciaria qualquer comentário sobre este, bem como sugestões para uma melhor solução, uma vez que há um.

  it "should list all related comments" do
@post.stub!(:approved_is).and_return([Factory(:comment, {:body => 'Comment #1', :post_id => @post.id}), 
                                      Factory(:comment, {:body => 'Comment #2', :post_id => @post.id})])
render "posts/show.html.erb"
response.should contain("Joe User says")
response.should contain("Comment #1")
response.should contain("Comment #2")

final

Ele lê um pouco desagradável.

Você poderia fazer algo como:

it "shows only approved comments" do
  comments << (1..3).map { Factory.create(:comment, :approved => true) }
  pending_comment = Factory.create(:comment, :approved => false)
  comments << pending_comments
  @post.approved.should_not include(pending_comment)
  @post.approved.length.should == 3
end

Ou algo nesse sentido. Especificação do comportamento, algum método aprovado deve retornar comentários para um post aprovado. Isso poderia ser um método simples ou um named_scope. E pendentes faria algo óbvio assim.

Você também pode ter uma fábrica para: pending_comment, algo como:

Factory.define :pending_comment, :parent => :comment do |p|
  p.approved = false
end

Ou, se falsa é o padrão, você poderia fazer a mesma coisa para:. Approved_comments

Eu realmente gosto de abordagem de Nick. Eu tive o mesmo problema mim e eu era capaz de fazer o seguinte. Acredito mock_model iria funcionar tão bem.

post = stub_model(Post)
assigns[:post] = post
post.stub!(:comments).and_return([stub_model(Comment)])
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top