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

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

May 24, 2015

Download

Technology

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).
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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