utilização de mock objects em testes unitários

40
Utilização de Mock Objects em Testes Unitários Nuno Caneco http://netpont o.org 29ª Reunião Lisboa - 26/05/2012

Upload: comunidade-netponto

Post on 24-May-2015

2.797 views

Category:

Technology


2 download

DESCRIPTION

Apresentação do Nuno Caneco sobre Utilização de Mock Objects em Testes Unitários na 29a Reunião Presencial da Comunidade NetPonto em Lisboa (http://netponto.org).

TRANSCRIPT

Page 1: Utilização de Mock Objects em Testes Unitários

Utilização de Mock Objects em Testes UnitáriosNuno Caneco

http://netponto.org29ª Reunião Lisboa - 26/05/2012

Page 2: Utilização de Mock Objects em Testes Unitários

Patrocinador “GOLD”

Page 4: Utilização de Mock Objects em Testes Unitários

Nuno CanecoConsultor Sénior na |create|it|

Áreas de interesse:• SOA e Integração• WCF• desenvolvimento core • Dependency Injection.

Page 5: Utilização de Mock Objects em Testes Unitários

Agenda

• Unit tests• Mocking frameworks• Demo• Considerações de arquitectura• Dicas

Page 6: Utilização de Mock Objects em Testes Unitários

Testes e mais testes…

Testes de carga

Testes unitários

Testes funcionais

Testes de sistema

Testes de integração

Testes de aceitação

Testes de performance

Testes de segurança

Testes de usabilidade

Page 7: Utilização de Mock Objects em Testes Unitários

Testes unitários• Objectivo:– Testar a lógica de um método de forma isolada, tendo em

conta os vários inputs possíveis e tendo em atenção casos de fronteira e valores inválidos.

• Características:– Repetíveis – Idempotentes– Não depender de outros testes– Inócuos

Page 8: Utilização de Mock Objects em Testes Unitários

Exemplo [TestClass] public class SaleRecordsReaderTest { private SaleRecordsReader GetReader() { return new SaleRecordsReader(); }

[TestMethod] public void ListSaleRecordTest() { var reader = GetReader();

var saleRecords = reader.ListSaleRecords();

Assert.IsNotNull(saleRecords); Assert.IsTrue(saleRecords.Count > 0); } }

Page 9: Utilização de Mock Objects em Testes Unitários

Alguns impedimentos e dificuldades

• UI: É difícil de testar código de interface– HTML/Javascript

• Acessibilidade– dos métodos: private, protected– da classe: internal

• Dependências– Persistência: BD, Lista de SharePoint– Sistemas externos– Utilização de providers: Membership providers, …

• Classes binded a determinados contextos– Ex.: CodeBehind de páginas .ASPX

Page 10: Utilização de Mock Objects em Testes Unitários

Mitos• “O meu código é perfeito!! Não é preciso testar.”

• “Não vale a pena fazer testes unitários. Basta clicar naquele link e pronto… Está testado!”

• “O projecto precisa de tempo para fazer testes unitários”

• “Eh pá… tenho que ter uma BD com dados de teste…”

• “Tenho muitas dependências. Não é possível abstrair-me dos sistemas externos”

Page 11: Utilização de Mock Objects em Testes Unitários

Mitos• “O meu código é perfeito!! Não é preciso testar.”

• “Não vale a pena fazer testes unitários. Basta clicar naquele link e pronto… Está testado!”

• “O projecto precisa de tempo para fazer testes unitários”

• “Eh pá… tenho que ter uma BD com dados de teste…”

• “Tenho muitas dependências. Não é possível abstrair-me dos sistemas externos”

Page 12: Utilização de Mock Objects em Testes Unitários

Motivação

Sistemas externosBD

Serviços

Business

DAL/RAL

Sistema

Page 13: Utilização de Mock Objects em Testes Unitários

Mocks com unit testsIn object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways.

A computer programmer typically creates a mock object to test the behavior of some other object, in much the same way that a car designer uses a crash test dummy to simulate the dynamic behavior of a human in vehicle impacts.

http://en.wikipedia.org/wiki/Mock_object

Page 14: Utilização de Mock Objects em Testes Unitários

Estratégia de implementação1. Gerar mock

– Usar framework de mocking para gerar mocks das dependências da classe a testar

2. Substituir dependência pelo mock– Inicializar classe a ser testada com o mock em substituição da implementação “real”

3. Programa o comportamento do mock– Programar os mocks para retornar determinados outputs em função dos inputs

• Valores de retorno• Excepções

4. Aferir o comportamento da classe em teste

Page 15: Utilização de Mock Objects em Testes Unitários

E que tal um exemplo?

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

Page 16: Utilização de Mock Objects em Testes Unitários

E que tal um exemplo?

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

Page 17: Utilização de Mock Objects em Testes Unitários

E que tal um exemplo?

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

Page 18: Utilização de Mock Objects em Testes Unitários

E que tal um exemplo?

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

Page 19: Utilização de Mock Objects em Testes Unitários

E que tal um exemplo?

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

CustomerManagerTest

Page 20: Utilização de Mock Objects em Testes Unitários

E que tal um exemplo?

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

CustomerManagerTest

CustomerReaderMock invoiceReaderMock

Page 21: Utilização de Mock Objects em Testes Unitários

E que tal um exemplo?

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

CustomerManagerTest

CustomerReaderMock invoiceReaderMock

Page 22: Utilização de Mock Objects em Testes Unitários

E que tal um exemplo?

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

CustomerManagerTest

CustomerReaderMock invoiceReaderMock

Page 23: Utilização de Mock Objects em Testes Unitários

E que tal um exemplo?

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

CustomerManagerTest

CustomerReaderMock invoiceReaderMock

Os mocks substituem as classes reais no contexto de um teste unitário

Page 24: Utilização de Mock Objects em Testes Unitários

O objectivo• Evitar dependências– Dados (base-de-dados, configuração, …)– Estado de sistemas externos (CRM, ERP, …)– Contas de utilizador– Setup de ambientes com dados de teste

• Testar vários cenários de negócio e condições de fronteira– Nulos, valores inválidos, decisões em função de valores

específicos

Page 25: Utilização de Mock Objects em Testes Unitários

Aplicabilidade

• A todo o código C# que seja testável–Serviços WCF–Aplicações MVC–Aplicações WPF–…

Page 26: Utilização de Mock Objects em Testes Unitários

Frameworks de mocking • Microsoft Moles (Fakes no VS11)• NMock• EasyMock.NET• TypeMock Isolator (Commercial / Paid)• Rhino Mocks• Moq• NSubstitute• JustMock (Commercial / Paid)• FakeItEasy

Page 27: Utilização de Mock Objects em Testes Unitários

Caso de uso

https://github.com/nmcc/unit-test-mock-demo

demonstração

Page 28: Utilização de Mock Objects em Testes Unitários

Questões?

Page 29: Utilização de Mock Objects em Testes Unitários

Considerações de arquitectura• É necessário fazer override do método .Equals() para os

objectos de input dos métodos

• Construtor que receba as interfaces das dependências

• Todas as dependências devem ser declaradas como interfaces– Usar “Ctrl+R, I” para gerar interfaces automaticamente

• É conveniente que os testes herdem de uma classe base que contém os mocks

Page 30: Utilização de Mock Objects em Testes Unitários

Dependency Injection

• Substituição das dependências é automática

• Evita múltiplos construtores das classes a testar

• Código de inicialização do container fica na classe base de testes

Page 31: Utilização de Mock Objects em Testes Unitários

Técnica: Mocks de dependências directas

CustomerManager

ICustomerReader

CustomerReader

IInvoiceReader

InvoiceReader

CustomerManagerTest

CustomerReaderMock InvoiceReaderMock

Page 32: Utilização de Mock Objects em Testes Unitários

Técnica:Mock das fronteiras

Sistemas externosBD

Serviços

Business

DAL/RAL

Sistema

Page 33: Utilização de Mock Objects em Testes Unitários

Dicas• Classe de teste junto à classe testada

– Ajuda a lembrar que existem testes – Utilizar #if para não compilar testes em Release

• Mock das fronteiras da aplicação– Permite atingir coverage elevada com menor número de testes

• Usar uma classe base para declarar os mocks

• Usar dependency injection– Permite injectar automaticamente os mocks numa classe base– Evitando a repetição da criação dos mocks pelas várias classes de teste

Page 34: Utilização de Mock Objects em Testes Unitários

Prós e contras

+ confiança no código + confiança em

refactorizações Minimiza testes funcionais Utilização de mocks

“descomplica” testes unitários Execução automatizada com

integração contínua

Testes têm que ser mantidos O código pode ter que ser

estruturado para ser testável Nem todo o código é testável

Page 35: Utilização de Mock Objects em Testes Unitários

ReferênciasRhino mocks– http://hibernatingrhinos.com/open-source/rhino-mocks

Demo– https://github.com/nmcc/unit-test-mock-demo

Page 36: Utilização de Mock Objects em Testes Unitários

Patrocinador “GOLD”

Page 38: Utilização de Mock Objects em Testes Unitários

Questões?

Page 39: Utilização de Mock Objects em Testes Unitários

Próximas reuniões presenciais

• 26-05-2012 – Maio• 02-06-2012 – Junho (Coimbra)• 16-06-2012 – Junho• 21-07-2012 – Julho

Reserva estes dias na agenda! :)

Page 40: Utilização de Mock Objects em Testes Unitários

Obrigado!

Nuno Caneco

Mail/MSN: [email protected]: http://blogit.create.pt/blogs/nunocaneco/Twitter: @NunoCanecoGamertag: nunocaneco