SlideShare une entreprise Scribd logo
1  sur  15
PowerMock
TDD User Group - Milano 03/10/2017
Massimo Groppelli
Cos’è PowerMock
PowerMock è un potente framework Java, che permette di scrivere test unitari per del codice che
normalmente non sarebbe testabile.
PowerMock estende alcuni tra i più famosi framework di mocking disponibili per il linguaggio come
EasyMock e Mockito. In questo talk ci occuperemo dell’integrazione con Mockito, ovvero PowerMockito.
Principali funzionalità che PowerMock aggiunge a Mockito:
● Mocking di classi finali, metodi statici e costruttori.
● Verifica delle invocazioni di metodi privati.
● Soppressione di comportamenti indesiderati (side effects) di metodi e classi.
PowerMock implementa le funzionalità sopra elencate, grazie alla combinazione di molteplici tecniche, a
partire dalla semplice introspezione tramite reflection per arrivare ad un classloader personalizzato ed
alla manipolazione del bytecode tramite instrumentazione.
Due parole su Mockito
Mockito è il più famoso framework di mocking per Java ed una tra le 10 librerie più utilizzate in assoluto
per il linguaggio.
● E’ un framework intuitivo, flessibile e divertente da utilizzare.
● Si basa su un approccio No expect-run-verify, non ha il concetto di expectation, ma solo le fasi di
stubbing e verification sui collaboratori.
● Si possono creare due tipologie di test doubles, i mock e gli spy per il partial mocking che come
vedremo è molto importante in ottica PowerMock.
@Test
public void test()
{
// Fixture.
final MyInterface mockDependency = Mockito.mock(MyInterface.class);
// Stubbing.
Mockito.when(mockDependency.method(Mockito.eq("testparam"))).thenReturn("testresult");
// Run Test.
final String result = new SystemUnderTest(mockDependency).methodToTest("testparam");
// Assertion.
Assert.assertEquals("Composizione stringa risultato", "prefix-testresult-suffix", result);
// Verification.
Mockito.verify(mockDependency, Mockito.times(1)).method(Mockito.eq("testparam"));
}
Ecosistema dei test
TEST DI ACCETTAZIONE
Funziona tutto il sistema?
(Altre definizioni: functional, customer, system tests)
TEST DI INTEGRAZIONE
Funziona il nostro codice rispetto a del
codice che non possiamo modificare?
(framework pubblico / librerie di altri gruppi di lavoro)
TEST UNITARI
I nostri oggetti svolgono correttamente le
loro responsabilità ed è comodo utilizzarli?
Classificazione livelli di test:
Growing Object-Oriented Software, Guided by Tests
PowerMock è uno strumento che si può utilizzare durante la scrittura di test di integrazione e soprattutto
unitari che misurano la qualità interna (codice facile da capire e da modificare) del sistema.
Perché questo talk?
Vorrei condividere la mia esperienza rispondendo ad un pò di domande……..
● PowerMock serve solo per testare codice di legacy e/o scritto male?
● Quanto il design delle nostre applicazioni dipende da limiti degli strumenti che utilizziamo per i test?
● Come PowerMock influenza le scelte di design?
● Può PowerMock aiutarci nel processo di refactor e come?
● Può mancare uno strumento come PowerMock nella cassetta degli attrezzi di chi pratica la TDD?
PowerMock è la chiave per eliminare il concetto di design testabile.
Design testabile e buon design
DESIGN TESTABILE
Il design testabile misura quanto è facile testare il codice, NON se è possibile testarlo.
Regole per isolare in modo semplice e veloce il codice sotto test dal resto del sistema.
● Istanziare una classe.
● Sostituire un’implementazione.
● Simulare differenti scenari.
● Invocare sul S.U.T (System under test) uno specifico flusso di controllo dal codice di test.
BUON DESIGN Spesso un design testabile corrisponde ad un buon design, ma non sempre.
Linee guida del design testabile
● Evitare metodi privati complessi, testare solo metodi pubblici.
● Evitare classi e metodi finali, non si possono creare sottotipi.
● Evitare metodi static se richiesta sostituzione in futuro.
● Utilizzare la keyword new con molta attenzione, è alto il rischio di creare accoppiamento.
● Evitare di gestire la logica che potrebbe essere sostituita nel costruttore.
● Evitare di creare singleton, meglio creare componenti con scope singleton.
● Favorire il riuso del codice per composizione, l’ereditarietà ok per polimorfismo, non per il riuso del
codice.
● Creare wrapper sulle librerie di terze parti, niente mocking su codice che non ci appartiene.
Più il codice è difficile da testare e più sarà difficile da modificare al prossimo cambio di requisiti!
Effetti collaterali
CLASSI E METODI FINALI
Critica: Una classe dovrebbe essere pensata per essere estesa.
Effetto: Si rinuncia ad un buon design per i limiti del tool di test.
Mockito nella versione 2 ha introdotto la possibilità di creare mock su classi final.
METODI PRIVATI
Critica: In alcuni contesti serve testare o verificare lo stato interno di un componente.
Effetto: Si cambia la visibilità di alcuni metodi per la fase di test.
L’annotazione @VisibleForTesting di Guava è stata creata proprio per documentare questa
violazione dell’incapsulamento.
Effetti collaterali
CLASSI E METODI STATICI
Critica: Alcune responsabilità sono statiche di natura e non siamo maghi per prevedere il futuro.
Effetto: Nel dubbio si rinuncia a creare classi statiche anche quando si dovrebbe.
Tante factory non statiche, codice scomodo da gestire ed aumento footprint.
WRAPPER DI LIBRERIE
Critica: E’ costoso fare classi wrapper ogni volta che si deve utilizzare codice che non ci
appartiene.
Effetto: Tendenza a creare molte classi senza valore aggiunto che fanno aumentare la codebase.
Si reinventa la ruota.
Metodi statici e classi finali
public class NewUserService
{
private final UserRepository userRepo;
public NewUserService(UserRepository userRepo)
{
this.userRepo = userRepo;
}
public User createNewUser(String name)
{
// Utilizzo metodo statico.
String newRandomTmpPwd = User.newTempPassword(20);
final User user = new User(name, newRandomTmpPwd);
// Collaborazione con il repository.
this.userRepo.saveOrUpdate(user);
return user;
}
}
Metodi statici e classi finali
Metodi statici e classi finali
@RunWith(PowerMockRunner.class)
@PrepareForTest( { UserRepository.class, User.class })
public class NewUserServiceTest
{
@Test
public void test()
{
// Fixture.
UserRepository mockUserRepo = PowerMockito.mock(UserRepository.class);
User newUserExpected = new User("massimo", "newPwdForTest");
// Stubbing.
PowerMockito.mockStatic(User.class);
Mockito.when(User.newTempPassword(Mockito.anyInt())).thenReturn("newPwdForTest");
// Run Test.
NewUserService serviceUnderTest = new NewUserService(mockUserRepo);
User newUserResult = serviceUnderTest.createNewUser("massimo");
// Assertion.
Assert.assertEquals(newUserExpected, newUserResult);
// Verification.
Mockito.verify(mockUserRepo, Mockito.times(1)).saveOrUpdate(Mockito.eq(newUserExpected));
}
}
Metodi privati
public class PrivateMethodClass
{
public int bigMethod(String argStr, int argInt) throws IOException
{
return this.privateToTest(argStr, argInt) + 10;
}
private int privateToTest(String argStr, int argInt) throws IOException
{
int newArgInt = this.privateToStub(argStr);
this.execute(newArgInt, argInt);
return newArgInt + 10;
}
private int privateToStub(String string)
{
return string.length() + 1000;
}
private void execute(int arg1, int arg2) throws IOException
{
try( BufferedWriter newBufferedWriter = Files.newBufferedWriter(Paths.get("myFile.txt"));)
{
newBufferedWriter.write(String.valueOf(arg1 + arg2)); // side effects.
}
}
}
Metodi privati
@RunWith(PowerMockRunner.class)
@PrepareForTest(PrivateMethodClass.class)
public class PrivateMethodExampleTest
{
@Test
public void testPrivateMethod() throws Exception
{
// Fixture.
PrivateMethodClass classUnderTest = PowerMockito.spy(new PrivateMethodClass());
// - No side effects.
Method method = PowerMockito.method(PrivateMethodClass.class, "execute", int.class, int.class);
PowerMockito.suppress(method);
// Stubbing.
PowerMockito.doReturn(20).when(classUnderTest, "privateToStub", "param");
// Run Test.
int result = Whitebox.invokeMethod(classUnderTest, "privateToTest", "param", 10);
// Assertion.
Assert.assertEquals(30, result);
// Verification.
PowerMockito.verifyPrivate(classUnderTest, Mockito.times(1)).invoke("execute", 20, 10);
}
}
Difetti di PowerMock
● Non è uno strumento per principianti.
● Si rischia di creare troppe dipendenze implicite.
● Può mandare in crash la JVM solamente per una annotazione messa nel posto sbagliato.
● Stack di difficile comprensione in debug.
● Va in conflitto con altri tools che a loro volta manipolano il bytecode a runtime, come succede per
alcuni framework di code coverage. E’ in corso una migrazione a ByteBuddy per risolvere il problema.

Contenu connexe

Tendances

Una fugace occhiata al Test Driven Development (2006)
Una fugace occhiata al Test Driven Development  (2006)Una fugace occhiata al Test Driven Development  (2006)
Una fugace occhiata al Test Driven Development (2006)Roberto Bettazzoni
 
Baby Steps TripServiceKata
Baby Steps TripServiceKataBaby Steps TripServiceKata
Baby Steps TripServiceKataAndrea Francia
 
Codice di qualità con VS2010 (TDD)
Codice di qualità con VS2010 (TDD)Codice di qualità con VS2010 (TDD)
Codice di qualità con VS2010 (TDD)XeDotNet
 
Meetup Code Garden Roma e Java User Group Roma: metodi asincroni con Spring -...
Meetup Code Garden Roma e Java User Group Roma: metodi asincroni con Spring -...Meetup Code Garden Roma e Java User Group Roma: metodi asincroni con Spring -...
Meetup Code Garden Roma e Java User Group Roma: metodi asincroni con Spring -...Codemotion
 
Lezione 4: I tool Ant e Subversion
Lezione 4: I tool Ant e SubversionLezione 4: I tool Ant e Subversion
Lezione 4: I tool Ant e SubversionAndrea Della Corte
 
Software testing with mocking framework (Android App)
Software testing with mocking framework (Android App)Software testing with mocking framework (Android App)
Software testing with mocking framework (Android App)gioacchinolonardo
 
Lezione 7: Design Pattern Comportamentali
Lezione 7: Design Pattern ComportamentaliLezione 7: Design Pattern Comportamentali
Lezione 7: Design Pattern ComportamentaliAndrea Della Corte
 
TDD patterns and TDD strategies
TDD patterns and TDD strategiesTDD patterns and TDD strategies
TDD patterns and TDD strategiesAlessandro Ceseno
 
Googletest, tdd e mock
Googletest, tdd e mockGoogletest, tdd e mock
Googletest, tdd e mockyuroller
 

Tendances (12)

Una fugace occhiata al Test Driven Development (2006)
Una fugace occhiata al Test Driven Development  (2006)Una fugace occhiata al Test Driven Development  (2006)
Una fugace occhiata al Test Driven Development (2006)
 
Baby Steps TripServiceKata
Baby Steps TripServiceKataBaby Steps TripServiceKata
Baby Steps TripServiceKata
 
Codice di qualità con VS2010 (TDD)
Codice di qualità con VS2010 (TDD)Codice di qualità con VS2010 (TDD)
Codice di qualità con VS2010 (TDD)
 
Metodi asincroni in spring
Metodi asincroni in springMetodi asincroni in spring
Metodi asincroni in spring
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
Meetup Code Garden Roma e Java User Group Roma: metodi asincroni con Spring -...
Meetup Code Garden Roma e Java User Group Roma: metodi asincroni con Spring -...Meetup Code Garden Roma e Java User Group Roma: metodi asincroni con Spring -...
Meetup Code Garden Roma e Java User Group Roma: metodi asincroni con Spring -...
 
Lezione 4: I tool Ant e Subversion
Lezione 4: I tool Ant e SubversionLezione 4: I tool Ant e Subversion
Lezione 4: I tool Ant e Subversion
 
Software testing with mocking framework (Android App)
Software testing with mocking framework (Android App)Software testing with mocking framework (Android App)
Software testing with mocking framework (Android App)
 
Lezione 7: Design Pattern Comportamentali
Lezione 7: Design Pattern ComportamentaliLezione 7: Design Pattern Comportamentali
Lezione 7: Design Pattern Comportamentali
 
TDD patterns and TDD strategies
TDD patterns and TDD strategiesTDD patterns and TDD strategies
TDD patterns and TDD strategies
 
Googletest, tdd e mock
Googletest, tdd e mockGoogletest, tdd e mock
Googletest, tdd e mock
 

Similaire à PowerMock TDD User Group Milano

Slide evento Code Refactoring JavaScript
Slide evento Code Refactoring JavaScriptSlide evento Code Refactoring JavaScript
Slide evento Code Refactoring JavaScriptLuca Pagliaro
 
Delphi & Dintorni Webinar - Diventa un mago del Testing
Delphi & Dintorni Webinar - Diventa un mago del TestingDelphi & Dintorni Webinar - Diventa un mago del Testing
Delphi & Dintorni Webinar - Diventa un mago del TestingMarco Breveglieri
 
Rich client application: MVC4 + MVVM = Knockout.js
Rich client application: MVC4 + MVVM = Knockout.jsRich client application: MVC4 + MVVM = Knockout.js
Rich client application: MVC4 + MVVM = Knockout.jsGiorgio Di Nardo
 
Software Testing & Test Driven Development
Software Testing & Test Driven DevelopmentSoftware Testing & Test Driven Development
Software Testing & Test Driven DevelopmentSergio Santoro
 
Detailed Model Capture
Detailed Model CaptureDetailed Model Capture
Detailed Model Capturefcospito
 
Detailed Model Capture
Detailed Model CaptureDetailed Model Capture
Detailed Model Capturefcospito
 
MuleSoft_Meetup__Official__8_.pdf
MuleSoft_Meetup__Official__8_.pdfMuleSoft_Meetup__Official__8_.pdf
MuleSoft_Meetup__Official__8_.pdfFlorence Consulting
 
Milano Meetup #8 - Testing & Salesforce Integration
Milano Meetup #8 - Testing & Salesforce IntegrationMilano Meetup #8 - Testing & Salesforce Integration
Milano Meetup #8 - Testing & Salesforce IntegrationGonzalo Marcos Ansoain
 
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...MicheleDamian
 
Unit Test di Gabriele Seroni
Unit Test di Gabriele SeroniUnit Test di Gabriele Seroni
Unit Test di Gabriele SeroniGiuneco S.r.l
 
TDD in WordPress
TDD in WordPressTDD in WordPress
TDD in WordPresslucatume
 
Qualità del Software
Qualità del SoftwareQualità del Software
Qualità del SoftwareYeser Rema
 
Javaday 2006: Java 5
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5Matteo Baccan
 
Unit Tests VS End To End Tests
Unit Tests VS End To End TestsUnit Tests VS End To End Tests
Unit Tests VS End To End Testsmimmozzo_
 
Studio e implementazione di uno strumento di configurazione e visualizzazione...
Studio e implementazione di uno strumento di configurazione e visualizzazione...Studio e implementazione di uno strumento di configurazione e visualizzazione...
Studio e implementazione di uno strumento di configurazione e visualizzazione...Matteo Miotto
 
Unit testing in Visual Studio 2013
Unit testing in Visual Studio 2013Unit testing in Visual Studio 2013
Unit testing in Visual Studio 2013DomusDotNet
 
javaday 2006 - Tiger
javaday 2006 - Tigerjavaday 2006 - Tiger
javaday 2006 - TigerMatteo Baccan
 

Similaire à PowerMock TDD User Group Milano (20)

Slide evento Code Refactoring JavaScript
Slide evento Code Refactoring JavaScriptSlide evento Code Refactoring JavaScript
Slide evento Code Refactoring JavaScript
 
Delphi & Dintorni Webinar - Diventa un mago del Testing
Delphi & Dintorni Webinar - Diventa un mago del TestingDelphi & Dintorni Webinar - Diventa un mago del Testing
Delphi & Dintorni Webinar - Diventa un mago del Testing
 
Rich client application: MVC4 + MVVM = Knockout.js
Rich client application: MVC4 + MVVM = Knockout.jsRich client application: MVC4 + MVVM = Knockout.js
Rich client application: MVC4 + MVVM = Knockout.js
 
Unit testing 101
Unit testing 101Unit testing 101
Unit testing 101
 
Software Testing & Test Driven Development
Software Testing & Test Driven DevelopmentSoftware Testing & Test Driven Development
Software Testing & Test Driven Development
 
Detailed Model Capture
Detailed Model CaptureDetailed Model Capture
Detailed Model Capture
 
Detailed Model Capture
Detailed Model CaptureDetailed Model Capture
Detailed Model Capture
 
MuleSoft_Meetup__Official__8_.pdf
MuleSoft_Meetup__Official__8_.pdfMuleSoft_Meetup__Official__8_.pdf
MuleSoft_Meetup__Official__8_.pdf
 
Milano Meetup #8 - Testing & Salesforce Integration
Milano Meetup #8 - Testing & Salesforce IntegrationMilano Meetup #8 - Testing & Salesforce Integration
Milano Meetup #8 - Testing & Salesforce Integration
 
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
Analisi di prestazione dell'interprete tuProlog su piattaforma Java - Present...
 
Unit Test di Gabriele Seroni
Unit Test di Gabriele SeroniUnit Test di Gabriele Seroni
Unit Test di Gabriele Seroni
 
Tesi di Laurea
Tesi di LaureaTesi di Laurea
Tesi di Laurea
 
TDD in WordPress
TDD in WordPressTDD in WordPress
TDD in WordPress
 
Qualità del Software
Qualità del SoftwareQualità del Software
Qualità del Software
 
Javaday 2006: Java 5
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5
 
Unit Tests VS End To End Tests
Unit Tests VS End To End TestsUnit Tests VS End To End Tests
Unit Tests VS End To End Tests
 
App Engine + Python
App Engine + PythonApp Engine + Python
App Engine + Python
 
Studio e implementazione di uno strumento di configurazione e visualizzazione...
Studio e implementazione di uno strumento di configurazione e visualizzazione...Studio e implementazione di uno strumento di configurazione e visualizzazione...
Studio e implementazione di uno strumento di configurazione e visualizzazione...
 
Unit testing in Visual Studio 2013
Unit testing in Visual Studio 2013Unit testing in Visual Studio 2013
Unit testing in Visual Studio 2013
 
javaday 2006 - Tiger
javaday 2006 - Tigerjavaday 2006 - Tiger
javaday 2006 - Tiger
 

PowerMock TDD User Group Milano

  • 1. PowerMock TDD User Group - Milano 03/10/2017 Massimo Groppelli
  • 2. Cos’è PowerMock PowerMock è un potente framework Java, che permette di scrivere test unitari per del codice che normalmente non sarebbe testabile. PowerMock estende alcuni tra i più famosi framework di mocking disponibili per il linguaggio come EasyMock e Mockito. In questo talk ci occuperemo dell’integrazione con Mockito, ovvero PowerMockito. Principali funzionalità che PowerMock aggiunge a Mockito: ● Mocking di classi finali, metodi statici e costruttori. ● Verifica delle invocazioni di metodi privati. ● Soppressione di comportamenti indesiderati (side effects) di metodi e classi. PowerMock implementa le funzionalità sopra elencate, grazie alla combinazione di molteplici tecniche, a partire dalla semplice introspezione tramite reflection per arrivare ad un classloader personalizzato ed alla manipolazione del bytecode tramite instrumentazione.
  • 3. Due parole su Mockito Mockito è il più famoso framework di mocking per Java ed una tra le 10 librerie più utilizzate in assoluto per il linguaggio. ● E’ un framework intuitivo, flessibile e divertente da utilizzare. ● Si basa su un approccio No expect-run-verify, non ha il concetto di expectation, ma solo le fasi di stubbing e verification sui collaboratori. ● Si possono creare due tipologie di test doubles, i mock e gli spy per il partial mocking che come vedremo è molto importante in ottica PowerMock. @Test public void test() { // Fixture. final MyInterface mockDependency = Mockito.mock(MyInterface.class); // Stubbing. Mockito.when(mockDependency.method(Mockito.eq("testparam"))).thenReturn("testresult"); // Run Test. final String result = new SystemUnderTest(mockDependency).methodToTest("testparam"); // Assertion. Assert.assertEquals("Composizione stringa risultato", "prefix-testresult-suffix", result); // Verification. Mockito.verify(mockDependency, Mockito.times(1)).method(Mockito.eq("testparam")); }
  • 4. Ecosistema dei test TEST DI ACCETTAZIONE Funziona tutto il sistema? (Altre definizioni: functional, customer, system tests) TEST DI INTEGRAZIONE Funziona il nostro codice rispetto a del codice che non possiamo modificare? (framework pubblico / librerie di altri gruppi di lavoro) TEST UNITARI I nostri oggetti svolgono correttamente le loro responsabilità ed è comodo utilizzarli? Classificazione livelli di test: Growing Object-Oriented Software, Guided by Tests PowerMock è uno strumento che si può utilizzare durante la scrittura di test di integrazione e soprattutto unitari che misurano la qualità interna (codice facile da capire e da modificare) del sistema.
  • 5. Perché questo talk? Vorrei condividere la mia esperienza rispondendo ad un pò di domande…….. ● PowerMock serve solo per testare codice di legacy e/o scritto male? ● Quanto il design delle nostre applicazioni dipende da limiti degli strumenti che utilizziamo per i test? ● Come PowerMock influenza le scelte di design? ● Può PowerMock aiutarci nel processo di refactor e come? ● Può mancare uno strumento come PowerMock nella cassetta degli attrezzi di chi pratica la TDD? PowerMock è la chiave per eliminare il concetto di design testabile.
  • 6. Design testabile e buon design DESIGN TESTABILE Il design testabile misura quanto è facile testare il codice, NON se è possibile testarlo. Regole per isolare in modo semplice e veloce il codice sotto test dal resto del sistema. ● Istanziare una classe. ● Sostituire un’implementazione. ● Simulare differenti scenari. ● Invocare sul S.U.T (System under test) uno specifico flusso di controllo dal codice di test. BUON DESIGN Spesso un design testabile corrisponde ad un buon design, ma non sempre.
  • 7. Linee guida del design testabile ● Evitare metodi privati complessi, testare solo metodi pubblici. ● Evitare classi e metodi finali, non si possono creare sottotipi. ● Evitare metodi static se richiesta sostituzione in futuro. ● Utilizzare la keyword new con molta attenzione, è alto il rischio di creare accoppiamento. ● Evitare di gestire la logica che potrebbe essere sostituita nel costruttore. ● Evitare di creare singleton, meglio creare componenti con scope singleton. ● Favorire il riuso del codice per composizione, l’ereditarietà ok per polimorfismo, non per il riuso del codice. ● Creare wrapper sulle librerie di terze parti, niente mocking su codice che non ci appartiene. Più il codice è difficile da testare e più sarà difficile da modificare al prossimo cambio di requisiti!
  • 8. Effetti collaterali CLASSI E METODI FINALI Critica: Una classe dovrebbe essere pensata per essere estesa. Effetto: Si rinuncia ad un buon design per i limiti del tool di test. Mockito nella versione 2 ha introdotto la possibilità di creare mock su classi final. METODI PRIVATI Critica: In alcuni contesti serve testare o verificare lo stato interno di un componente. Effetto: Si cambia la visibilità di alcuni metodi per la fase di test. L’annotazione @VisibleForTesting di Guava è stata creata proprio per documentare questa violazione dell’incapsulamento.
  • 9. Effetti collaterali CLASSI E METODI STATICI Critica: Alcune responsabilità sono statiche di natura e non siamo maghi per prevedere il futuro. Effetto: Nel dubbio si rinuncia a creare classi statiche anche quando si dovrebbe. Tante factory non statiche, codice scomodo da gestire ed aumento footprint. WRAPPER DI LIBRERIE Critica: E’ costoso fare classi wrapper ogni volta che si deve utilizzare codice che non ci appartiene. Effetto: Tendenza a creare molte classi senza valore aggiunto che fanno aumentare la codebase. Si reinventa la ruota.
  • 10. Metodi statici e classi finali
  • 11. public class NewUserService { private final UserRepository userRepo; public NewUserService(UserRepository userRepo) { this.userRepo = userRepo; } public User createNewUser(String name) { // Utilizzo metodo statico. String newRandomTmpPwd = User.newTempPassword(20); final User user = new User(name, newRandomTmpPwd); // Collaborazione con il repository. this.userRepo.saveOrUpdate(user); return user; } } Metodi statici e classi finali
  • 12. Metodi statici e classi finali @RunWith(PowerMockRunner.class) @PrepareForTest( { UserRepository.class, User.class }) public class NewUserServiceTest { @Test public void test() { // Fixture. UserRepository mockUserRepo = PowerMockito.mock(UserRepository.class); User newUserExpected = new User("massimo", "newPwdForTest"); // Stubbing. PowerMockito.mockStatic(User.class); Mockito.when(User.newTempPassword(Mockito.anyInt())).thenReturn("newPwdForTest"); // Run Test. NewUserService serviceUnderTest = new NewUserService(mockUserRepo); User newUserResult = serviceUnderTest.createNewUser("massimo"); // Assertion. Assert.assertEquals(newUserExpected, newUserResult); // Verification. Mockito.verify(mockUserRepo, Mockito.times(1)).saveOrUpdate(Mockito.eq(newUserExpected)); } }
  • 13. Metodi privati public class PrivateMethodClass { public int bigMethod(String argStr, int argInt) throws IOException { return this.privateToTest(argStr, argInt) + 10; } private int privateToTest(String argStr, int argInt) throws IOException { int newArgInt = this.privateToStub(argStr); this.execute(newArgInt, argInt); return newArgInt + 10; } private int privateToStub(String string) { return string.length() + 1000; } private void execute(int arg1, int arg2) throws IOException { try( BufferedWriter newBufferedWriter = Files.newBufferedWriter(Paths.get("myFile.txt"));) { newBufferedWriter.write(String.valueOf(arg1 + arg2)); // side effects. } } }
  • 14. Metodi privati @RunWith(PowerMockRunner.class) @PrepareForTest(PrivateMethodClass.class) public class PrivateMethodExampleTest { @Test public void testPrivateMethod() throws Exception { // Fixture. PrivateMethodClass classUnderTest = PowerMockito.spy(new PrivateMethodClass()); // - No side effects. Method method = PowerMockito.method(PrivateMethodClass.class, "execute", int.class, int.class); PowerMockito.suppress(method); // Stubbing. PowerMockito.doReturn(20).when(classUnderTest, "privateToStub", "param"); // Run Test. int result = Whitebox.invokeMethod(classUnderTest, "privateToTest", "param", 10); // Assertion. Assert.assertEquals(30, result); // Verification. PowerMockito.verifyPrivate(classUnderTest, Mockito.times(1)).invoke("execute", 20, 10); } }
  • 15. Difetti di PowerMock ● Non è uno strumento per principianti. ● Si rischia di creare troppe dipendenze implicite. ● Può mandare in crash la JVM solamente per una annotazione messa nel posto sbagliato. ● Stack di difficile comprensione in debug. ● Va in conflitto con altri tools che a loro volta manipolano il bytecode a runtime, come succede per alcuni framework di code coverage. E’ in corso una migrazione a ByteBuddy per risolvere il problema.

Notes de l'éditeur

  1. Massimo Groppelli
  2. PowerMock è molto semplice da utilizzare soprattutto per chi già conosce Mockito, infatti il framework non mira a reinventare la ruota ma si integra molto bene tanto è vero che le API sono praticamente uguali a quelle dei framework di Mocking che estende.
  3. Dire che alcune linee guida sono validissime e vanno rispettate.