Mocks e Stubs com Rspec

mock-vs-stubs-clerb-presentation-1-728

Mocks e stubs são conceitos, muitas vezes de difícil compreensão, principalmente para desenvolvedores iniciantes em testes automatizados. Eu mesmo levei um tempinho para compreendê-los e nem sei se entendi muito bem. Por trás disso existe uma nomenclatura um tanto confusa e que não ajuda muito na compreensão dos conceitos. Vamos analisar como o Rspec trabalha com eles utilizando a biblioteca rspec-mocks.

Muitas vezes quando estamos escrevendo nossos testes, precisamos utilizar de objetos falsos. Em determinados cenários, o objeto real pode não estar disponível ou é necessário utilizar algum recurso externo que pode deixar o teste lento. Algumas vezes não precisamos testar o estado do objeto mas sim seu comportamento. Chamamos esses objetos falsos de Test Doubles ou Dublês de teste. Mocks e stubs são dois dos tipos especializados de doubles e são os mais utilizados.

Stubs

Simulam implementações dos objetos reais através de métodos que retornam valores pré-determinados. São métodos pré-configurados com as informações necessárias para a execução dos testes. Abaixo temos um exemplo de declaração de um test double.

  double = double('user', name: 'Tyrion Lanister')

O primeiro parâmetro é uma descrição do dublê que é usada na documentação e nas mensagens de falha. O segundo é o método stub setado com um valor qualquer. Vamos a um exemplo melhor. Queremos testar o método calculate_total_price da classe Order.


class Order
  attr_reader :total

  def calculate_total_price itens
    @total = 0
    itens.each { |item| @total += item.price }
  end

end

Podemos testar esse método sem instanciar o objeto real Item, através de stubs.


describe Order, "#calculate_total_price" do

  let(:itens) { [double(price: 10.0), double(price: 45.5)] }

  it "calculates the total price" do
    order = Order.new
    order.calculate_total_price(itens)

    expect(order.total).to eq(55.5)
  end

end

Na linha 3 setamos um array de doubles ao invés de uma array de objetos da classe Item. O teste irá passar. Isso é muito útil em testes  de unidade,, pois não precisamos acessar o banco de dados para pegar os dados do objeto Item que poderia ser um modelo do Active Record.

Mocks

São doubles pré-programados que irão criar expectativas que deverão ser satisfeitas pelos testes. Podemos usá-los quando queremos testar a chamada de uma api externa, por exemplo. Vamos dar uma olhada no exemplo abaixo.


class Westeros

  def geolocate(place)
    Geocoder.coordinates(place)
  end

end

O método geolocate da classe Westeros tem uma chamada da bilblioteca geocoder que retorna as coordenadas geográficas de um dado endereço. Precisamos testar se o método coordinates de Geocoder irá mesmo retornar as coordenadas? Acho que não. Os desenvolvedores da gem já fizeram isso. Precisamos mesmo é garantir que o método geolocate de Westeros irá chamar coordinates de Geocoder com o parâmetro correto. Para isso vamos usar um mock.


describe Westeros, "#geolocate" do

  it "retuns coordinates" do
    place = 'Ponta Tempestade, Westeros'
    westeros = Westeros.new

    expect(Geocoder).to receive(:coordinates).with(place)
    westeros.geolocate(place)
  end

end

Na linha 7 definimos as expectativas. Geocoder deve executar o método coordinates com place como argumento. O teste passa. Dessa forma testamos a interface de geocoder e não seu funcionamento interno. Um detalhe a parte é a dsl do rspec que deixa a leitura muito simples e agradável proporcionando um modo bastante elegante de se escrever testes.

conclusão

O rspec possui muitas outras inúmeras funcionalidades no que diz respeito a test doubles e testes regulares. A prática e a experiência irão melhorar ainda mais o entendimento dos conceitos de mocks e stubs, assim como os conceitos de testes automatizados. Existem uma infinidade de artigos sobre o assunto na internet. Vale a pena dar uma pesquisada no assunto.

Referências

https://github.com/rspec/rspec-mocks

http://www.infoq.com/br/articles/mocks-Arent-Stubs

Anúncios

Integrando backbone.js e devise

Imagine o seguinte cenário: queremos implementar uma autenticação de usuário em um sistema rails que utiliza o devise. No front-end, estamos utilizando o backbone.js. Não é uma tarefa das mais complicadas, mas que requer alguns artifícios e um bom conhecimento da api do devise.

Devise é uma gem desenvolvida pela galera da plataformatec, que nos proporciona uma api completa e flexível para soluções de autenticação em rails. Sua api já abstrái para o desenvolvedor funcionalidades como encriptação senha, Omniauth, confirmação por email, esqueceu sua senha, bloqueio de conta, entre outras coisas.

O backbone.js é uma biblioteca javascript para criação de web apps. Ele nos auxilia a trabalhar em aplicações javascript de maneira desacoplada do DOM. Com estruturas de model, collections, views e templates, nos proporciona uma melhor organização e modularização do código javascript, facilitando a compreensão e a manutenção. Chega de javascript macarrônico. Backbone trabalha nativamente com REST, logo, casa muito bem com aplicações rails, restful.

Continuar lendo

Rails Girls Belém

Ícones pixelizados de um coração e um erlenmeyer, com a inscrição 'Rails Girls'

Mais ou menos em Julho, começamos a entrar em contato com a organização internacional do evento e com isso conhecemos a Natalie Volk, que nos deu apoio e, com sua contribuição, fizemos chamadas para mais meninas participarem da organização.

A Natalie, a comunidade Tá Safo! e o time (organizadoras e coaches) foram fundamentais para que tomássemos mais iniciativa e rumo, porque sentíamos a responsabilidade de fazer um evento tão bom quanto os demais que acontecem em outros países e aqui no Brasil. Isso aumentava nosso comprometimento em fazer um evento que realmente trouxesse mais conhecimento e motivação para as meninas.

Com as reuniões, sempre vinham mais ideias e dessa maneira foi possível galgar verdadeiramente o acontecimento do evento. Tivemos treinamento com os coaches, o apoio e patrocínio de empresas que apostaram nesse evento e isso aumentou nossas expectativas ainda mais.

Depois que as inscrições começaram, vimos que o número de pessoas interessadas era muito grande em comparação ao que havíamos definido. Ficamos muito felizes com o interesse das meninas, até chegamos a cogitar um espaço maior, mas por ser o primeiro evento, optamos por não arriscar tanto. E desde o início, a comunidade Tá safo! foi a que mais apoiou, patrocinou e deu credibilidade a esse evento.

Time de organização e coaches

As inscrições estavam bombando e ainda tinha mais de uma semana para o evento acontecer, começamos a cogitar lugares maiores. Queríamos todas as meninas presentes. Decidimos fazer um grupo menor que realmente estivesse interessado. Acreditem, quase todas estavam interessadas! Recebemos inúmeros e-mails de meninas reclamando o motivo de não terem sido selecionadas. Ah, sem esquecer dos rapazes, muitos meninos queriam participar também! A organização do evento então deu os ponta-pés iniciais. Tudo estava arranjado e finalmente…

Continuar lendo