JMockit Framework Overview
-
Upload
mario-peshev -
Category
Technology
-
view
14.875 -
download
1
description
Transcript of JMockit Framework Overview
Mocking with JMockit
Mario PeshevDevriX CTO, SCJPConsultant, Trainer
http://www.linkedin.com/in/mpeshevhttp://devrix.com
Contents
• What is Mocking
• Where to use mocking
• JMockit introduction
• Expectations and Verifications
• Annotations and Coverage
• Comparison of mocking frameworks
What is Mocking
• Isolated class or method testing
• Ignore dependencies of related classes when not necessary
• Simplify testing environment by providing empty proxies instead of complex logical units
What is Mocking (2)
• A mock object represents a surreal interface or a class with modified output
• Code behind is being skipped to reduce the effort of initialization before running a test case
Mocking Scheme
DB Server
Web Server
Application with dependencies
MOCKED
MOCKED
Why mock?
• Replace all collaborators with mocks
• Avoid the use of Context with specific setup
• Test only the core functionality of a class or a method
Mocking advantages
• Remove dependencies from external libraries and servers:• Databases• Web servers• Sockets• Web services
• Less time for writing unit tests for legacy code
How does mocking work
• Two general types of mocking
• Proxy based• easymock, jmock
• Class loader remapping• jmockit, powermock
Proxy based
• Proxy based approach relies on reflection
• Java Reflection API is a powerful toolset to inspect Java code at runtime
• Different structures could be explored – classes, interfaces, fields, methods• Even private methods could be called
Proxy based (2)
• Reflection provides mechanism to create objects, invoke methods and access get/set field values and return types
• Interfaces could be implemented dynamically via java.lang. reflect.Proxy
• Proxy return values could be defined
Class loader mapping
• This method relies on the Instrumentation API
• Instrumentation API is a set of features since Java 5
• It allows remapping of the classes to be called by the VM
Instrumentation API
• In package java.lang.instrument• Provides services that allow Java agents
to instrument programs running on the JVM
• Instrumentation does direct bytecode modification of methods and classes• Uncatchable by debuggers
Instrumentation API (2)
Remapping example
• We have a Book class to define Book model behavior to a model.
• We need to separate DB logic dependences from the Book
• So we define BookMock class and Instrumentation remaps VM links from Book to BookMock.class
JMockit
JMockit
• Open source mocking library
• Under MIT license
• Collection of tools to be used in testing environment together with JUnit or TestNG framework
• Bytecode modifications done at runtime through internal ASM library
JMockit Components
• 6 components in the toolkit:• JMockit Core• JMockit Annotations• JMockit Expectations• JMockit Coverage• JMockit Hibernate Emulation• JMockit AOP
JMockit vs. the World
• JMockit is far more complex, but more powerful than the other mocking frameworks
• It allows mocking of static methods and final classes
• http://code.google.com/p/jmockit/wiki/MockingToolkitComparisonMatrix
JMockit inside
Expectations API
• Provides a record-replay model– Set one or more expectations– Define a real sample code using directly or
not the mocked object
• Automatic verification of all expected invocations is transparent with JUnit/TestNG connection
Expectations API (2)
• Mock types could be defined as instance fields of the test class or of an Expectations anonymous subclass inside the recording phase
new Expectations() {ClassToBeMocked mock; {
… }
}
new Expectations() {ClassToBeMocked mock; {
… }
}
Expectations API (3)
• Expectations could be specified of any kind of method invocation• Interfaces, abstract classes, concrete final or
non-final classes, static methods, constructors
• Private methods and constructors could have expectations too
Expectations API (4)
• By default, all expectations are strict– For each expectation a matching invocation is
expected and in the same order– If additional invocation to mocked
type/instance is detected, assertion error will be thrown too
• Non-strict expectations could be defined – singular or in a specific block
Expectations API (5)
• A non-strict expectations could be invoked any number of times (0…N) and in arbitrary order
• Unexpected invocations don’t cause errors to the test
• Mocked objects could be passed as test method parameters (TestNG included)
Expectations Sample
public class MockNoInterfaceClassTest { static class User {
String name() { return "joe";
} }
@Mocked User user; …
public class MockNoInterfaceClassTest { static class User {
String name() { return "joe";
} }
@Mocked User user; …
Expectations Sample (2)
…@Test public void mockNoInterfaceFinalClass() {
new Expectations() { {
user.name(); returns("fred"); }};
assertEquals("fred", user.name()); } }
…@Test public void mockNoInterfaceFinalClass() {
new Expectations() { {
user.name(); returns("fred"); }};
assertEquals("fred", user.name()); } }
Verifications API
• Additional phase for verify to the record-replay model
• All other invocations in the test can be verified to have occurred (or not) after the replay phase• It is possible to not have expectations but
verifications only
Verification API (2)
• Doesn’t make sense when we have 100% strict expectations
• However, when we have mocked types with non-strict expectations, this is where we could make sure invocations are being called as required
Verification Demo
static class UserService {
void populateUser() { User user = new User(); user.setName("fred"); user.setAge(31); } }
@Mocked User user;…
static class UserService {
void populateUser() { User user = new User(); user.setName("fred"); user.setAge(31); } }
@Mocked User user;…
Verification Demo (2)
…@Test public void verifyInternalMethods() { new UserService().populateUser(); new FullVerificationsInOrder() { { User user = new User(); user.setName("fred"); user.setAge(withAny(1)); } };
}
…@Test public void verifyInternalMethods() { new UserService().populateUser(); new FullVerificationsInOrder() { { User user = new User(); user.setName("fred"); user.setAge(withAny(1)); } };
}
Verification Types
• InOrder• The order of invocations in the Verification
block has to match the original order
• Full• Guarantees that _all_ invocations in the
replay block must be verified in verification block
• Could define FullVerificationsInOrder too
JMockit test method template
@Test public void aTestMethod(<any number of mock parameters>) {
// Record phase: expectations on mocks are recorded; empty if there is nothing to record.
// Replay phase: invocations on mocks are "replayed"; here the code under test is exercised.
// Verify phase: expectations on mocks are verified; empty if there is nothing to verify.
}
@Test public void aTestMethod(<any number of mock parameters>) {
// Record phase: expectations on mocks are recorded; empty if there is nothing to record.
// Replay phase: invocations on mocks are "replayed"; here the code under test is exercised.
// Verify phase: expectations on mocks are verified; empty if there is nothing to verify.
}
JMockit Mockups
• A different kind of API which adds functionality to mocking types
• Mock classes are defined and applied for a method or a testing class• Mock methods are @Mock annotated and
behavior is defined that replaces the original method body
• Number of invocations could be set too
State-oriented mocking
• Useful for testing the argument values instead of checking invocations • Allows complex data handling and
verifications
• Achievable with mockit.Mockup<T> generic class for mockup creation
Annotations Demo
@Test public void mockSystemNanoTime() { new MockUp<System>() { @Mock @SuppressWarnings("unused") long nanoTime() { return 0L; } }; assertSame(0L, System.nanoTime()); }
@Test public void mockSystemNanoTime() { new MockUp<System>() { @Mock @SuppressWarnings("unused") long nanoTime() { return 0L; } }; assertSame(0L, System.nanoTime()); }
JMockit Coverage
• Code coverage API
• Bytecode modification done only on runtime (constructions on demand)
• 1 .jar only – based on “convention over configuration”
• Automatic analyze of all classes (specific set could be defined later)
JMockit Coverage (2)
• Output could be as XHTML report or any serialized file
• Line-coverage and Path-coverage metrics
• Incremental test runner• Analyze only modified local files
Coverage Report
Hibernate Emulation
• Designed for the speed of unit test and functionality of Hibernate-based integration tests
• Fake Hibernate 3 Core API Implementation
• O/R mapping data is ignored as well as real connections to database
JMockit installation
• Download jmockit from project homepage: http://code.google.com/p/jmockit/downloads/list
• Copy jmockit.jar in your Eclipse project
• Add the -Djavaagent=jmockit.jar (with relative or absolute path) to your JVM arguments when running Eclipse
• Run with JDK and not JRE
JMockit with TestNG
• For TestNG support with JMockit, the Initializer listener needs to be added– -listener mockit.integration.testng.Initializer as program argument
– Or as a TestNG XML parameter in testng.xml:
Running JMockit with TestNG
Eclipse Demo
@Mocked and @Injectable
• @Mocked• All instances of the given class (current and
future) are mocked
• @Injectable• Only the given instance of the class is
mocked
JMockit vs. PowerMock
• PowerMock is only extension to other mocking frameworks
• JMockit provides a new Expectations API
• PowerMock API is low level and requires specific API calls
• Methods are mocked in a declarative way with specified partial mocking
JMockit vs. PowerMock (2)
• JMockit has support for mocking equals(), hashCode() and overriden methods
• PowerMock uses custom class loaders which is heavy and could lead to conflicts
• The –javaagent approach in JMockit is simpler and safer
JMockit vs. Mockito
• Every Mockito object invocation requires a call to its mocking API (between record and verify phases)
• Mockito has inconsistences in the syntax used for invocation of mocked methods
• Mockito has different syntax for calling methods returning values and void methods
JMockit vs. Mockito (2)
• In Mockito all invocations to mock objects during the test are allowed, never expected• Verification is not automatic
• JMockit Expectations & Verifications gives plenty of options for best combination of strict (expected) and non-strict (allowed) mock invocations
JMockit vs. Mockito (3)
• Mockito needs additional object for in order and full verifications
• JMockit gives a combination of VerificationsInOrder or FullVerifications (or FullVerificationsInOrder)
Questions?
DevriX Ltd
Consulting services
• Consulting in Java/PHP related technologies, database systems and platforms:
• GWT• Swing• WordPress• CakePHP
Trainings
• Core Java• Java and Database Management
• Swing API• JEE• Tools and Automation Testing
• Design Patterns• …
http://devrix.com