Download - Mock Objects

Transcript
Page 1: Mock Objects

1Mock objects, João Pascoal Faria, 2007

TQS - Teste e Qualidade de Software

(Software Testing and Quality)

Mock Objects

João Pascoal Faria

[email protected] www.fe.up.pt/~jpf

(baseado em slides de ex-alunos)

Page 2: Mock Objects

2Mock objects, João Pascoal Faria, 2007

Índice

Definição

Quando usar

Detalhes técnicos

Exemplo prático

Frameworks

Exemplo com jMock 2

Page 3: Mock Objects

3Mock objects, João Pascoal Faria, 2007

Definição

Objectos simulados que imitam o comportamento de objectos reais de um modo controlado [wikipedia]

Criam-se para fazer testes ao comportamento de outros

objectos• Tal como os crash test dummies são

usados nos testes de automóveis

Page 4: Mock Objects

4Mock objects, João Pascoal Faria, 2007

Quando usar

Quando o objecto real...• ainda não existe

• retorna um resultado não determinístico- Hora Actual, Temperatura Actual

• tem estados difíceis de atingir- um erro da rede

• precisa de incluir informação e métodos exclusivamente para uso nos testes e não para a sua tarefa

• é lento- uma base de dados completa que tenha que ser inicializada

antes do teste

Page 5: Mock Objects

5Mock objects, João Pascoal Faria, 2007

Detalhes técnicos

Permitir que o objecto que o invoca não saiba se está a usar um objecto real ou um mock object

Têm a mesma interface que os objectos que simulam• Ambos implementam a mesma interface

• Mock object estende objecto real

Page 6: Mock Objects

6Mock objects, João Pascoal Faria, 2007

Exemplo prático

public class Convert {

public static double getTemperatureInCelcius(City city){double tempF;Sensor sensor = city.getSensor();tempF = sensor.getCurrentTemperature();

//Convert Fahreneit to Celsius degreesreturn (tempF-32.0)*(5.0/9.0);

}

…}

Resultado não

determinístico

Classe City não existe

Page 7: Mock Objects

7Mock objects, João Pascoal Faria, 2007

public class Convert {…

public static double getTemperatureInCelcius(City city){double tempF;Sensor sensor = city.getSensor();tempF = sensor.getCurrentTemperature();

return (tempF-32.0)*(5.0/9.0);}

…}

public class MockSensor extends Sensor {…

public double getCurrentTemperature() {//MOCKreturn 72.5;

}}

Exemplo prático (continuação)

Resultado conhecido (=22.5ºC)

Page 8: Mock Objects

8Mock objects, João Pascoal Faria, 2007

public class Convert {…

public static double getTemperatureInCelcius(City city){double tempF;Sensor sensor = city.getSensor();tempF = sensor.getCurrentTemperature();

return (tempF-32.0)*(5.0/9.0);}

…}

Exemplo prático (continuação)

Escrever método para

controlar valor de retorno

public class MockCity implements City {

…private Sensor curSensor;

public Sensor getSensor() {//MOCKreturn curSensor;

}

public void setSensor(Sensor s){//MOCKthis.curSensor = s;

}}

Page 9: Mock Objects

9Mock objects, João Pascoal Faria, 2007

Exemplo prático (continuação)

public class TestConvert extends TestCase {

public void testGetTemperatureInCelcius() {MockCity city = new MockCity();MockSensor sensor = new MockSensor();city.setSensor(sensor);

assertEquals(22.5, Convert.getTemperatureInCelcius(city));}

}

Page 10: Mock Objects

10Mock objects, João Pascoal Faria, 2007

Em suma…

Escrever classes mock

Estender classe real

Implementar interface• Implementar todos os seus métodos

Reescrever (overwrite) os métodos a simular

Criar e executar teste

Page 11: Mock Objects

11Mock objects, João Pascoal Faria, 2007

Frameworks

Facilitam e tornam mais rápida a criação dos Mock Objects• Não é necessário escrever o código das classes mock

Permitem criação a partir de:• Interfaces

• Classes

Permitem definir expectativas flexíveis• Número de chamadas a métodos

• Valores de retorno

• Valores dos parâmetros

• Lançamento de excepções

Integram com JUnit (Java), NUnit (.Net), etc.

Fornecem normalmente APIs extensíveis

Page 12: Mock Objects

12Mock objects, João Pascoal Faria, 2007

Frameworks

Java• jMock (http://www.jmock.org)

• EasyMock (http://www.easymock.org)

• rMock (http://rmock.sourceforge.net)

• MockCreator (http://mockcreator.sourceforge.net)

• MockLib (http://mocklib.sourceforge.net)

C#• MockLib (http://sourceforge.net/projects/mocklib)

• Rhino Mocks (http://www.ayende.com/)

• NMock (http://nmock.org)

Page 13: Mock Objects

13Mock objects, João Pascoal Faria, 2007

Frameworks

Ruby• Mocha (http://mocha.rubyforge.org)

• RSpec (http://rspec.rubyforge.org)

• FlexMock (http://onestepback.org/software/flexmock)

Outras linguagens• C++

• Javascript

• Perl

• Python

• ActionScript

• …

Page 14: Mock Objects

14Mock objects, João Pascoal Faria, 2007

Exemplo com jMock 2 – código a testar

public class Convert {

public static double getTemperatureInCelcius(City city){double tempF;Sensor sensor = city.getSensor();tempF = sensor.getCurrentTemperature();

//Convert Fahreneit to Celsius degreesreturn (tempF-32.0)*(5.0/9.0);

}}

Resultado não

determinístico

Classe City não existe

public interface City { Sensor getSensor(); }

// Nesta versão de jMock só faz "mocks" de interfacespublic interface Sensor {double getCurrentTemperature();}

Não

imp

lem

en

tad

os!

Page 15: Mock Objects

15Mock objects, João Pascoal Faria, 2007

import org.jmock.integration.junit3.MockObjectTestCase;import org.jmock.Expectations;

public class JMockTestConvert extends MockObjectTestCase { // set up final City mockCity = mock(City.class); final Sensor mockSensor = mock(Sensor.class);

public void testGetTemperatureInCelcius() { // expectations checking(new Expectations() {{ one(mockCity).getSensor(); will(returnValue(mockSensor)); one(mockSensor).getCurrentTemperature(); will(returnValue(72.5)); }}); // execute double result = Convert.getTemperatureInCelcius(mockCity); // test assertEquals(22.5, result); }}

Exemplo com jMock 2 – código de teste

Page 16: Mock Objects

16Mock objects, João Pascoal Faria, 2007

Exercício Com base na rotina de conversão de um número para extenso (ver

“Extensos.java”), desenvolver (segundo a abordagem TDD) na mesma classe Extensos uma método estático MoneyExt(double m, Currency c) para converter um valor monetário m para extenso em maiúsculas. O 2º argumento é uma instância de uma interface que define métodos para obter a designação por extenso da unidade monetária e fracções no singular e plural (exemplo: euro, euros, cêntimo, cêntimos), bem como o número de dígitos a usar na parte fraccionária (exemplo: 2), de acordo com a seguinte sintaxe (em Java usar String em vez de string):

public interface Currency { string getCurrencyNamePlural(); string getCurrencyNameSingular(); string getFractionsNameSingular(); string getFractionsNamePlural(); int getFractionsDigits(); }

Criar uma mock class MockCurrency que implementa a interface Currency só para efeitos de teste.

Repetir usando um framework como o jMock, em vez de criar uma mock class

Page 17: Mock Objects

17Mock objects, João Pascoal Faria, 2007

Referências e mais informação

www.jmock.org

www.mockobjects.com