Testando relacionamentos no Rails

Read this acticle in English

Estive procurando por uma maneira elegante de testar relacionamentos utilizando Rails, e achei interessante como pouca gente está preocupada com isso. Na maioria das vezes, dizem simplesmente que isto é função do próprio framework. Tudo bem, o has_many e belongs_to (esqueça que existe o HBTM) já foram devidamente testados, mas é importante saber que o que cabe a você testar o que você escreve no seu código. Portanto, se você quer ter certeza que a linha has_many :comments realmente existe, você deve escrever um teste para ela. Então, resolvi listar algumas abordagens:

1 – Utilizando fixtures:

No começo, pensei em utilizar as fixtures, mas usando relacionamentos dentro delas. É uma solução simples, porém traz um revés. Quando utilizamos um relacionamento dentro das fixtures, e este relacionamento não está explicitado nos models, será retornado um erro, ao invés de uma falha. Por exemplo:

# post.rb

class Post < ActiveRecord::Base

end# comment.rb

class Comment < ActiveRecord::Base

end

# posts.yml

testing_relationships:

  title: Hello World

  body: Hello...

# comments.yml

commenting_relationships:

  body: I disagree!

  author: Filipe Coimbra

  post:  testing_relationships

Como não foi explicitamente dito que Comment belongs_to :post, ao se executar a fixture comments.yml será retornado um erro. Além disso, o relacionamento contrário, Post has_many :comments não será testado.

2 – Novamente utilizando fixtures:

Depois, encontrei este artigo, que também utiliza fixtures com uma abordagem diferente (e mais Rails 1.x) que é definir apenas a chave estrangeira na fixture. Assim, não seria retornado erro.
É funcional, mas eu quero apenas testar se as linhas de relacionamento estão definidas nos models. O resto, fica por conta do ActiveRecord. Além disso, não quero usar fixtures como se fossem testes, já que, primeiro, não são documentadas automaticamente (como no caso dos métodos de teste) e porque, caso você mude a estrutura da sua tabela, poderá ter seus testes quebrados por causa das fixtures que não refletem as mudanças.

3 – A opção errada que funciona:

Acabei utilizando a solução mais lógica, e baseada neste post do Err The Blog.

# post_spec.rb

describe Post do

  before(:each) do

    @post = Post.new

  end  it "should be related to comments" do

comment = Comment.new(:body => "Testing relationships")

    @post.comments << comment

    @post.comments.should include(comment)

  end

end

# comment_spec.rb

describe Comment do

  before(:each) do

    @comment = Comment.new

  end

it "should be related to a post"

    post = Post.new

    @comment.post = post

    @comment.should equal(post)

    @comment.post.should equal(post)

  end

end

É simples, mas… por que é errada? Quando fazemos “@post.comments << comment”, estamos chamando o método comments do objeto @post. Como não foi declarado que Post has_many :comments, este método não existirá. Ela funciona porque o rSpec não acusará o erro, e apenas retornará uma falha no teste.
Ainda assim, prefiro essa solução porque eu não precisarei lidar com fixtures.

Explore posts in the same categories: rails, testing

Tags: ,

You can comment below, or link to this permanent URL from your own site.

One Comment on “Testando relacionamentos no Rails”


  1. [...] Testing relationships in Rails Ler este artigo em português [...]


Comment: