SlideShare ist ein Scribd-Unternehmen logo
1 von 12
Unit testing with PowerMock




          Open source project:
http ://code.google.com/p/powermock/
PowerMock features



Mocking static methods
Mocking final methods or classes
Mocking private methods
Mock construction of new objects
Partial Mocking
Replay and verify all
Mock Policies
Test listeners
Add to maven project


<properties>
  <powermock.version>1.4.12</powermock.version>
</properties>
<dependencies>
  <dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-easymock</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
  </dependency>
</dependencies>
Add to ant project


Copy jars to the test folder:

cglib-nodep-2.2.2.jar
easymock-3.1.jar
javassist-3.16.1-GA.jar
powermock-easymock-1.4.12-full.jar
objenesis-1.2.jar

Add jars to the classpath for junit task:

<path id="test.classpath">
<path refid="plugin.classpath" />
<fileset dir="${app.server.lib.portal.dir}" includes="commons-io.jar" />
<fileset dir="${project.dir}/lib" includes="junit.jar" />
<fileset dir="${project.dir}/lib/test" includes="*.jar" />
<pathelement location="test-classes" />
</path>
Class under test example


public class ClassUnderTest {
  private MyService myService;
  public String getMaxAmountForTemplate() {
    String template = TemplateUtil.getTemplate("1");
    BigDecimal maxAmount = myService.getMaxAmount();
    return TemplateUtil.applyTemplate(template, maxAmount);
  }
}

interface MyService {
   BigDecimal getMaxAmount();
}
class TemplateUtil {
  public static String getTemplate(String templateId) {
    return "ID";
  }
  public static String applyTemplate(String template, Object ... params) {
    return template + params.toString();
  }
}
Unit test implementation



import java.math.BigDecimal;

public class ClassUnderTestTest {
  private ClassUnderTest classUnderTest;
  @org.junit.Test
  public void getMaxAmountForTemplate() {
    classUnderTest = new ClassUnderTest();
    org.junit.Assert.assertEquals("Should be ID100", "ID100",
     classUnderTest.getMaxAmountForTemplate());
  }
}
Unit test implementation with mocks


@PrepareForTest({TemplateUtil.class })
@RunWith(PowerMockRunner.class)
public class ClassUnderTestTest {
 private ClassUnderTest classUnderTest;
 @org.junit.Test
 public void getMaxAmountForTemplate() throws Exception {
  classUnderTest = new ClassUnderTest();
  PowerMock.mockStatic(TemplateUtil.class);
  EasyMock.expect(TemplateUtil.getTemplate(EasyMock.eq("1"))).andReturn("ID");
  EasyMock.expect(TemplateUtil.applyTemplate(EasyMock.eq("ID"), (BigDecimal)
    EasyMock.anyObject())).andReturn("IDMOCK");
  MyService myService = EasyMock.createMock(MyService.class);
  Field field = classUnderTest.getClass().getDeclaredField("myService");
  field.setAccessible(true);
  field.set(classUnderTest, myService);
  EasyMock.expect(myService.getMaxAmount()).andReturn(new BigDecimal("100"));

        PowerMock.replayAll();
        EasyMock.replay(myService);
        org.junit.Assert.assertEquals("Should be IDMOCK", "IDMOCK",
         classUnderTest.getMaxAmountForTemplate());
        EasyMock.verify(myService);
        PowerMock.verifyAll();
    }
}
Use capture with EasyMock


  public void getMaxAmountForTemplate() throws Exception {
    classUnderTest = new ClassUnderTest();
    PowerMock.mockStatic(TemplateUtil.class);
    EasyMock.expect(TemplateUtil.getTemplate(EasyMock.eq("1"))).andReturn("ID");
    Capture<BigDecimal> capturedMaxAmount = new Capture<BigDecimal>();
    EasyMock.expect(TemplateUtil.applyTemplate(EasyMock.eq("ID"),
     EasyMock.capture(capturedMaxAmount))).andReturn("IDMOCK");
    MyService myService = EasyMock.createMock(MyService.class);
...
    EasyMock.replay(myService);
    org.junit.Assert.assertEquals("Should be IDMOCK", "IDMOCK",
     classUnderTest.getMaxAmountForTemplate());
    org.junit.Assert.assertEquals("100",
     capturedMaxAmount.getValue().toString() );
    EasyMock.verify(myService);
    PowerMock.verifyAll();
  }
Code emulation in mock objects


@org.junit.Test
public void getMaxAmountForTemplate() throws Exception {
 classUnderTest = new ClassUnderTest();
 PowerMock.mockStatic(TemplateUtil.class);
 EasyMock.expect(TemplateUtil.getTemplate(EasyMock.eq("1"))).andReturn("ID");
 EasyMock.expect(TemplateUtil.applyTemplate(EasyMock.eq("ID"), (BigDecimal)
  EasyMock.anyObject())).andAnswer(new IAnswer<String>() {
     public String answer() throws Throwable {
       return EasyMock.getCurrentArguments()[0].toString() +
  EasyMock.getCurrentArguments()[1].toString();
     }
 });

 MyService myService = EasyMock.createMock(MyService.class);
 Field field = classUnderTest.getClass().getDeclaredField("myService");
 field.setAccessible(true);
 field.set(classUnderTest, myService);
 EasyMock.expect(myService.getMaxAmount()).andReturn(new BigDecimal("100"));

 PowerMock.replayAll();
 EasyMock.replay(myService);
 org.junit.Assert.assertEquals("Should be ID100", "ID100",
  classUnderTest.getMaxAmountForTemplate());
Skip static initialization for classes under test


public class TemplateUtil {
  static {
    initDatabase();
  }
  public static String getTemplate(String templateId) {
    return "ID";
  }
  public static String applyTemplate(String template, Object ... params) {
    return template + params[0].toString();
  }
}

@SuppressStaticInitializationFor("TemplateUtil")
@RunWith(PowerMockRunner.class)
public class ClassUnderTestTest {
 private ClassUnderTest classUnderTest;
F.I.R.S.T. properties of unit tests




   Fast
     Many hundreds or thousands per second
   Isolates
     Failure reasons became obvious
   Repeatable
     Run repeatedly in any order, any time
   Self-validating
     No manual validation required
   Timely
     Written before the code
Internet resources




http ://stackoverflow.com/search?q=powermock


http ://code.google.com/p/powermock/w/list

Weitere ähnliche Inhalte

Was ist angesagt?

Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Ryosuke Uchitate
 
The Ring programming language version 1.10 book - Part 82 of 212
The Ring programming language version 1.10 book - Part 82 of 212The Ring programming language version 1.10 book - Part 82 of 212
The Ring programming language version 1.10 book - Part 82 of 212Mahmoud Samir Fayed
 
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, ClimacellLiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, ClimacellDroidConTLV
 
The Ring programming language version 1.7 book - Part 32 of 196
The Ring programming language version 1.7 book - Part 32 of 196The Ring programming language version 1.7 book - Part 32 of 196
The Ring programming language version 1.7 book - Part 32 of 196Mahmoud Samir Fayed
 
MegaScriptSample - Released x-x-15
MegaScriptSample - Released x-x-15MegaScriptSample - Released x-x-15
MegaScriptSample - Released x-x-15Bob Powers
 
The Ring programming language version 1.5.1 book - Part 27 of 180
The Ring programming language version 1.5.1 book - Part 27 of 180The Ring programming language version 1.5.1 book - Part 27 of 180
The Ring programming language version 1.5.1 book - Part 27 of 180Mahmoud Samir Fayed
 
Тестирование на Android с Dagger 2
Тестирование на Android с Dagger 2Тестирование на Android с Dagger 2
Тестирование на Android с Dagger 2Kirill Rozov
 
Learning Java 4 – Swing, SQL, and Security API
Learning Java 4 – Swing, SQL, and Security APILearning Java 4 – Swing, SQL, and Security API
Learning Java 4 – Swing, SQL, and Security APIcaswenson
 
Clustering your Application with Hazelcast
Clustering your Application with HazelcastClustering your Application with Hazelcast
Clustering your Application with HazelcastHazelcast
 
Introduction to Reactive Extensions (Rx)
Introduction to Reactive Extensions (Rx)Introduction to Reactive Extensions (Rx)
Introduction to Reactive Extensions (Rx)Tamir Dresher
 
Dealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring testsDealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring testsAlexander Tarlinder
 
Introduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizerIntroduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizerMydbops
 
yagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guideyagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guideMert Can Akkan
 
Architecture Components
Architecture Components Architecture Components
Architecture Components DataArt
 
Building responsive application with Rx - confoo - tamir dresher
Building responsive application with Rx - confoo - tamir dresherBuilding responsive application with Rx - confoo - tamir dresher
Building responsive application with Rx - confoo - tamir dresherTamir Dresher
 
The Ring programming language version 1.5.4 book - Part 70 of 185
The Ring programming language version 1.5.4 book - Part 70 of 185The Ring programming language version 1.5.4 book - Part 70 of 185
The Ring programming language version 1.5.4 book - Part 70 of 185Mahmoud Samir Fayed
 

Was ist angesagt? (20)

Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
The Ring programming language version 1.10 book - Part 82 of 212
The Ring programming language version 1.10 book - Part 82 of 212The Ring programming language version 1.10 book - Part 82 of 212
The Ring programming language version 1.10 book - Part 82 of 212
 
Guice2.0
Guice2.0Guice2.0
Guice2.0
 
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, ClimacellLiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
LiveData on Steroids - Giora Shevach + Shahar Ben Moshe, Climacell
 
The Ring programming language version 1.7 book - Part 32 of 196
The Ring programming language version 1.7 book - Part 32 of 196The Ring programming language version 1.7 book - Part 32 of 196
The Ring programming language version 1.7 book - Part 32 of 196
 
MegaScriptSample - Released x-x-15
MegaScriptSample - Released x-x-15MegaScriptSample - Released x-x-15
MegaScriptSample - Released x-x-15
 
The Ring programming language version 1.5.1 book - Part 27 of 180
The Ring programming language version 1.5.1 book - Part 27 of 180The Ring programming language version 1.5.1 book - Part 27 of 180
The Ring programming language version 1.5.1 book - Part 27 of 180
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
Тестирование на Android с Dagger 2
Тестирование на Android с Dagger 2Тестирование на Android с Dagger 2
Тестирование на Android с Dagger 2
 
Learning Java 4 – Swing, SQL, and Security API
Learning Java 4 – Swing, SQL, and Security APILearning Java 4 – Swing, SQL, and Security API
Learning Java 4 – Swing, SQL, and Security API
 
Clustering your Application with Hazelcast
Clustering your Application with HazelcastClustering your Application with Hazelcast
Clustering your Application with Hazelcast
 
Introduction to Reactive Extensions (Rx)
Introduction to Reactive Extensions (Rx)Introduction to Reactive Extensions (Rx)
Introduction to Reactive Extensions (Rx)
 
Dealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring testsDealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring tests
 
Introduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizerIntroduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizer
 
yagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guideyagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guide
 
Architecture Components
Architecture Components Architecture Components
Architecture Components
 
Building responsive application with Rx - confoo - tamir dresher
Building responsive application with Rx - confoo - tamir dresherBuilding responsive application with Rx - confoo - tamir dresher
Building responsive application with Rx - confoo - tamir dresher
 
React lecture
React lectureReact lecture
React lecture
 
The Ring programming language version 1.5.4 book - Part 70 of 185
The Ring programming language version 1.5.4 book - Part 70 of 185The Ring programming language version 1.5.4 book - Part 70 of 185
The Ring programming language version 1.5.4 book - Part 70 of 185
 

Ähnlich wie Unit testing with mock libs

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Sustaining Test-Driven Development
Sustaining Test-Driven DevelopmentSustaining Test-Driven Development
Sustaining Test-Driven DevelopmentAgileOnTheBeach
 
Unit Testing at Scale
Unit Testing at ScaleUnit Testing at Scale
Unit Testing at ScaleJan Wloka
 
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014First Tuesday Bergen
 
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Pragmatic unittestingwithj unit
Pragmatic unittestingwithj unitPragmatic unittestingwithj unit
Pragmatic unittestingwithj unitliminescence
 
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...solit
 
Testing microservices: Tools and Frameworks
Testing microservices: Tools and FrameworksTesting microservices: Tools and Frameworks
Testing microservices: Tools and FrameworksPiotr Mińkowski
 
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...Databricks
 
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...Matthew Tovbin
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEDarwin Durand
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 

Ähnlich wie Unit testing with mock libs (20)

Android TDD
Android TDDAndroid TDD
Android TDD
 
Wicket 6
Wicket 6Wicket 6
Wicket 6
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Sustaining Test-Driven Development
Sustaining Test-Driven DevelopmentSustaining Test-Driven Development
Sustaining Test-Driven Development
 
Unit Testing at Scale
Unit Testing at ScaleUnit Testing at Scale
Unit Testing at Scale
 
Jersey Guice AOP
Jersey Guice AOPJersey Guice AOP
Jersey Guice AOP
 
Dependency Injection for Android
Dependency Injection for AndroidDependency Injection for Android
Dependency Injection for Android
 
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
 
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#18.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
 
guice-servlet
guice-servletguice-servlet
guice-servlet
 
Pragmatic unittestingwithj unit
Pragmatic unittestingwithj unitPragmatic unittestingwithj unit
Pragmatic unittestingwithj unit
 
Power mock
Power mockPower mock
Power mock
 
Diifeerences In C#
Diifeerences In C#Diifeerences In C#
Diifeerences In C#
 
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
 
single-value annotation
single-value annotationsingle-value annotation
single-value annotation
 
Testing microservices: Tools and Frameworks
Testing microservices: Tools and FrameworksTesting microservices: Tools and Frameworks
Testing microservices: Tools and Frameworks
 
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
 
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 

Unit testing with mock libs

  • 1. Unit testing with PowerMock Open source project: http ://code.google.com/p/powermock/
  • 2. PowerMock features Mocking static methods Mocking final methods or classes Mocking private methods Mock construction of new objects Partial Mocking Replay and verify all Mock Policies Test listeners
  • 3. Add to maven project <properties> <powermock.version>1.4.12</powermock.version> </properties> <dependencies> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-easymock</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> </dependencies>
  • 4. Add to ant project Copy jars to the test folder: cglib-nodep-2.2.2.jar easymock-3.1.jar javassist-3.16.1-GA.jar powermock-easymock-1.4.12-full.jar objenesis-1.2.jar Add jars to the classpath for junit task: <path id="test.classpath"> <path refid="plugin.classpath" /> <fileset dir="${app.server.lib.portal.dir}" includes="commons-io.jar" /> <fileset dir="${project.dir}/lib" includes="junit.jar" /> <fileset dir="${project.dir}/lib/test" includes="*.jar" /> <pathelement location="test-classes" /> </path>
  • 5. Class under test example public class ClassUnderTest { private MyService myService; public String getMaxAmountForTemplate() { String template = TemplateUtil.getTemplate("1"); BigDecimal maxAmount = myService.getMaxAmount(); return TemplateUtil.applyTemplate(template, maxAmount); } } interface MyService { BigDecimal getMaxAmount(); } class TemplateUtil { public static String getTemplate(String templateId) { return "ID"; } public static String applyTemplate(String template, Object ... params) { return template + params.toString(); } }
  • 6. Unit test implementation import java.math.BigDecimal; public class ClassUnderTestTest { private ClassUnderTest classUnderTest; @org.junit.Test public void getMaxAmountForTemplate() { classUnderTest = new ClassUnderTest(); org.junit.Assert.assertEquals("Should be ID100", "ID100", classUnderTest.getMaxAmountForTemplate()); } }
  • 7. Unit test implementation with mocks @PrepareForTest({TemplateUtil.class }) @RunWith(PowerMockRunner.class) public class ClassUnderTestTest { private ClassUnderTest classUnderTest; @org.junit.Test public void getMaxAmountForTemplate() throws Exception { classUnderTest = new ClassUnderTest(); PowerMock.mockStatic(TemplateUtil.class); EasyMock.expect(TemplateUtil.getTemplate(EasyMock.eq("1"))).andReturn("ID"); EasyMock.expect(TemplateUtil.applyTemplate(EasyMock.eq("ID"), (BigDecimal) EasyMock.anyObject())).andReturn("IDMOCK"); MyService myService = EasyMock.createMock(MyService.class); Field field = classUnderTest.getClass().getDeclaredField("myService"); field.setAccessible(true); field.set(classUnderTest, myService); EasyMock.expect(myService.getMaxAmount()).andReturn(new BigDecimal("100")); PowerMock.replayAll(); EasyMock.replay(myService); org.junit.Assert.assertEquals("Should be IDMOCK", "IDMOCK", classUnderTest.getMaxAmountForTemplate()); EasyMock.verify(myService); PowerMock.verifyAll(); } }
  • 8. Use capture with EasyMock public void getMaxAmountForTemplate() throws Exception { classUnderTest = new ClassUnderTest(); PowerMock.mockStatic(TemplateUtil.class); EasyMock.expect(TemplateUtil.getTemplate(EasyMock.eq("1"))).andReturn("ID"); Capture<BigDecimal> capturedMaxAmount = new Capture<BigDecimal>(); EasyMock.expect(TemplateUtil.applyTemplate(EasyMock.eq("ID"), EasyMock.capture(capturedMaxAmount))).andReturn("IDMOCK"); MyService myService = EasyMock.createMock(MyService.class); ... EasyMock.replay(myService); org.junit.Assert.assertEquals("Should be IDMOCK", "IDMOCK", classUnderTest.getMaxAmountForTemplate()); org.junit.Assert.assertEquals("100", capturedMaxAmount.getValue().toString() ); EasyMock.verify(myService); PowerMock.verifyAll(); }
  • 9. Code emulation in mock objects @org.junit.Test public void getMaxAmountForTemplate() throws Exception { classUnderTest = new ClassUnderTest(); PowerMock.mockStatic(TemplateUtil.class); EasyMock.expect(TemplateUtil.getTemplate(EasyMock.eq("1"))).andReturn("ID"); EasyMock.expect(TemplateUtil.applyTemplate(EasyMock.eq("ID"), (BigDecimal) EasyMock.anyObject())).andAnswer(new IAnswer<String>() { public String answer() throws Throwable { return EasyMock.getCurrentArguments()[0].toString() + EasyMock.getCurrentArguments()[1].toString(); } }); MyService myService = EasyMock.createMock(MyService.class); Field field = classUnderTest.getClass().getDeclaredField("myService"); field.setAccessible(true); field.set(classUnderTest, myService); EasyMock.expect(myService.getMaxAmount()).andReturn(new BigDecimal("100")); PowerMock.replayAll(); EasyMock.replay(myService); org.junit.Assert.assertEquals("Should be ID100", "ID100", classUnderTest.getMaxAmountForTemplate());
  • 10. Skip static initialization for classes under test public class TemplateUtil { static { initDatabase(); } public static String getTemplate(String templateId) { return "ID"; } public static String applyTemplate(String template, Object ... params) { return template + params[0].toString(); } } @SuppressStaticInitializationFor("TemplateUtil") @RunWith(PowerMockRunner.class) public class ClassUnderTestTest { private ClassUnderTest classUnderTest;
  • 11. F.I.R.S.T. properties of unit tests  Fast Many hundreds or thousands per second  Isolates Failure reasons became obvious  Repeatable Run repeatedly in any order, any time  Self-validating No manual validation required  Timely Written before the code