Testando o Método Create de um Controller com Nested Attributes

Estava eu essa semana tentando terminar os scripts de teste de um projeto. Tudo estava dando certo, terminei de cobrir todos os testes dos models e comecei a trabalhar nos controllers, até que me deparei com o teste do método create de um controller que utiliza nested_attributes para cadastro de um model e suas associações. A estrutura dos models e controller é semelhante a essa:

# app/models/author.rb
class Author < ActiveRecord::Base
has_many :posts, dependent: :destroy
  accepts_nested_attributes_for :posts, allow_destroy: true
  ...
end
# app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :author
  ...
end
# app/controllers/authors_controller.rb
class AuthorsController < ApplicationController
...
  def create
@author = Author.new author_params
    if @author.save
flash[:success] = 'Autor cadastrado com sucesso!'
redirect_to @author
else
render 'new'
end
end
  ...
  private
  def author_params
params.require(:author).permit(:name, posts_attributes: [
:title, :content,
:id, :_destroy
])
end
  ...
end

Eu utilizo FactoryGirl para facilitar meus testes, a principio pesquisei por algum método mágico dessa gema que convertesse a Hash dos atributos exatamente para o aceito pelo parâmetro do controller (com nested_attributes). Passei longos 30 minutos e não achei nada, então resolvi fazer a seguinte gambiarra no script de teste:

require 'rails_helper'
RSpec.describe AuthorsController, type: :controller do
...
  describe 'POST #create' do
context 'with valid attributes' do
let!(author_params) do
FactoryGirl.attributes_for(:author)
.merge(posts_attributes: [FactoryGirl.attributes_for(:post)])
end
      it 'creates a new author' do
expect {
post :create, author: author_params
}.to change { Author.count }.by(1)
end
      it 'redirects to :show view' do
post :create, author: author_params
expect(response).to redirect_to(Author.last)
end
end
    ...
end
  ...
end

Acredito que este não seja a forma mais correta de testar esse tipo de situação, mas pra mim deu certo.

leia mais em: www.marceloperini.com.br

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.