0% found this document useful (0 votes)
105 views19 pages

Mastering Mock Objects: Advanced Unit Testing For Java

This document discusses using mock objects for advanced unit testing in Java. It introduces concepts like intercepting methods and declaring expectations with mock object frameworks. It covers tools like JMock and JMockit for creating mock objects in Java tests. The document compares different levels of testing from code logic to integration to function tests. It argues that unit tests should focus on testing code logic in isolation without runtime dependencies through the use of mock objects.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
105 views19 pages

Mastering Mock Objects: Advanced Unit Testing For Java

This document discusses using mock objects for advanced unit testing in Java. It introduces concepts like intercepting methods and declaring expectations with mock object frameworks. It covers tools like JMock and JMockit for creating mock objects in Java tests. The document compares different levels of testing from code logic to integration to function tests. It argues that unit tests should focus on testing code logic in isolation without runtime dependencies through the use of mock objects.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 19

Mastering Mock Objects

Advanced Unit Testing for Java


By Denilson Nastacio

Denilson Nastacio

14 years in software development Quality Enthusiast Rational Unified Process practitioner

RTP

Scrolls (http://rtpscrolls.blogspot.com) SourcePatch (http://sourcepatch.blogspot.com) LinkedIn (http://www.linkedin.com/in/nastacio)

Your Host

Concepts
Intercepting methods Declaring expectations Tools
3

Agenda

Code logic

Tests whether isolated methods respect their exposed contract Guarantees that there are no broken code paths No runtime dependencies: mock objects

C E

Integration test (by developer, not QA organization)

A D

Tests combination of classes and runtime environment Require runtime support Detect incompatibilities between components Residual code logic tests

A D

C E
4

Function test (by developer, not QA organization)


Real end-user scenarios Residual code logic and integration test.

Different levels of abstraction

QA System Test

QA Function Test

Function Integration

Dev

Runtime dependencies

Development

Code logic
5

Ideal resource allocation

Cost per volume of code

Complex
Create user accounts, upgrade OS, install fixpacks, etc

Slow
Minutes to recycle servers between tests

Unnecessary
During development, you want to test the code, purge logic errors before starting test integration 6

The case against system dependencies on unit testing

Classes tested in isolation Black box testing


Based on declared interfaces, not actual implementation

Guarantees that methods respect their declared interfaces


Good to validate public APIs Bad for validating exceptions related to environment problems

White box testing


Based on implementation, usually due to incomplete specifications Typical of test written after the fact Concerned with exhaustive test of all lines in the actual source code Good to verify exception handling when combined with mock objects
7

Code logic test

Mock environments for Java

Environment simulators

Respond like the real environment Pros: Simulate complex behavior without environment dependencies Cons: Few simulators available, maintaining a simulator rivals the complexity of maintaining a real application

Mock object frameworks


Same interfaces as the real environment Developer must preset the mock objects with the expected responses Pros: Mock objects can be generated quickly for any environment Cons: Presetting mock objects for unit tests may require lots of code
9

Classes of mock environments

JMockit

Instructs the JVM to replace calls to any method with code under your control One-two punch with JMock against bunkered initialization within the production code, such as calls to constructors or static methods Use JMockit to intercept calls to static methods deep into the production code and return JMock pre-programmed objects. http://jmockit.dev.java.net

JMock

Pre-program objects to expect calls and return values of your choice Instruct the production code to talk to mocked object instead of actual system dependency Mocks interfaces and classes. http://www.jmock.org 10

Mock libraries

@Test public void testTransferFunds() throws Exception { org.jmock.Mockery context = new Mockery(); context.setImposteriser(ClassImposteriser.INSTANCE); final float testAmount = 300; final BankAccount sourceAccount = context.mock(BankAccount.class, "source"); final BankAccount targetAccount = context.mock(BankAccount.class, "target"); org.jmock.Expectations expect = new Expectations() { { one(sourceAccount).withdraw(testAmount); one(targetAccount).deposit(testAmount); } }; context.checking(expect); Transaction tx = new Transaction(); tx.transferFunds(testAmount, sourceAccount, targetAccount); context.assertIsSatisfied(); }

Create mock Context Create mock instances Programs mock instances

Adds expectation to mock context.

Asks context whether all expectations were met.


11

Anatomy of JMock in a test fixture

@Mocked private final BankSOAUtil unused = null; @Test public void testBankAccountSOA() throws Exception { String inputDir = "abc"; final String inputFile = "AndrewBankAccountData.xml"; new mockit.Expectations() { { BankSOAUtil.getInputStream((URL)withNotNull()); returns(new FileInputStream(inputFile)); } }; // Bank account constructor reads its configuration using // BankSOAUtil.getInputStream BankAccount bc = new BankAccount("userid", "password"); Assert.assertEquals("Andrew", bc.getCustomerName()); }

Marking class to be mocked Inlined mocked expectation

Programming the expectation

12

Anatomy of JMockit in a test fixture Inlined mock

public void testBankAccountSOA() throws Exception {s Mockit.setUpMocks(MockBankSOAUtil.class); String inputFile = "AndrewBankAccountData.xml"; // Bank account constructor reads its configuration using // BankSOAUtil.getInputStream BankAccount bc = new BankAccount(...); Assert.assertEquals("Andrew", bc.getCustomerName()); Mockit.tearDownMocks(); } @MockClass(realClass = BankSOAUtil.class) public static class MockBankSOAUtil { private static String inputFile = null; @Mock(invocations = 1) public static InputStream getInputStream(URL inputUrl) throws IOException { return new FileInputStream(inputFile) ; } public static void setInputFile(String inputFile) { MockDogearUtil.inputFile = inputFile ; } }

Instructs the JVM about the mock classes to be used

Instructs the JVM to stop using JMockit mocks. Declares the production class to be mocked

Indicates which methods of the production class should be mocked 13

Anatomy of JMockit in a test fixture Using a mock class

JMockit
Can intercept any call to the JVM Added many improvements to expectation support during 2009 Supports bytecode level coverage metrics My new favorite

JMock
Used to have better control over behavior of mocked object My former favorite Needs production code to provide entry points to receive the mocked objects
14

Which one should I use?

Required versus allowed


Is it important that the mocked method be actually called? JMock: allowing/ignored/one

JMockit: Expectations, Verifications, and sub-classes

Specific versus loose

Is it important that the mocked method be actually called with a specific parameter?
Both JMock and JMockit offer out-of-the-box matchers for concepts like 'same value', 'same class', 'inherited from a class', 'null', 'not null', and others

Building mock expectations

What if results from a dependency matter?


} public class ExternalClass { public String somethingWithAReturnValue(String input) { return "DEF";

When results matter 1 of 3

final ExternalClass ecMock = context.mock(ExternalClass.class); org.jmock.Expectations expect = new org.jmock.Expectations() { { one(ecMock).somethingWithAReturnValue("specific value"); will(returnValue("someReturnValue")); } };

final ExternalClass ecMock = context.mock(ExternalClass.class); org.jmock.Expectations expect = new org.jmock.Expectations() { { one(ecMock).somethingWithAReturnValue(with(any(String.class))); will(returnValue("someReturnValue")); } };

Use with(any(Class <T> type)) to instruct the JMock mock to ignore input parameters

When results matter JMock 2 of 3

new };

mockit.Expectations () {
ExternalClass EcMock; { ecMock.somethingWithAReturnValue("specific value"); returns("someReturnValue")); }

new };

mockit.Expectations () { ExternalClass EcMock; { ecMock.somethingWithAReturnValue(withAny(""); returns("someReturnValue")); }

Use withAny(Class <T> type)) to instruct the JMockit mock to ignore input parameters

When results matter Jmockit - 3 of 3

DDTUnit

http://ddtunit.sourceforge.net/

Cobertura

http://cobertura.sourceforge.net/
Note: JMockit has its own code coverage support

19

Great companion tools

You might also like