DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Software Design and Architecture
  3. Security
  4. Using PowerMock to Mock Constructors

Using PowerMock to Mock Constructors

Roger Hughes user avatar by
Roger Hughes
·
Oct. 20, 11 · Interview
Like (2)
Save
Tweet
Share
70.16K Views

Join the DZone community and get the full member experience.

Join For Free

In my opinion, one of the main benefits of dependency injection is that you can inject mock and/or stub objects into your code in order to improve testability, increase test coverage and write better and more meaningful tests. There are those times, however, when you come across some legacy code that doesn’t use dependency injection and held together by composition rather than aggregation.

When this happens, you have three options:

  1. Ignore the problem and not write any tests.
  2. Refactor like mad, changing everything to use dependency injection.
  3. Use PowerMock to mock constructors

Obviously, option 1 isn’t a serious option, and although I’d recommend refactoring to move everything over to dependency injection, that takes time and you have to be pragmatic. That’s where PowerMock comes in... this blog demonstrates how to use PowerMock to mock a constructor, which means that when your code calls new it doesn’t create a real object, it creates a mock object.

To demonstrate this idea, the first thing we need is some classes to test, which are shown below.
public class AnyOldClass {

  public String someMethod() {
    return "someMethod";
  }
}
public class UsesNewToInstantiateClass {

  public String createThing() {

    AnyOldClass myclass = new AnyOldClass();

    String returnValue = myclass.someMethod();
    return returnValue;
  }
}

The first class, AnyOldClass, is the class that the code instantiates by calling new. In this example, as the name suggests, it can be anything.

The second class, the aptly named UsesNewToInstantiateClass, has one method, createThing(), which when called does a:

    AnyOldClass myclass = new AnyOldClass();

This is all pretty straight forward, so we’ll move quickly on to the PowerMock assisted JUnit test:

import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.easymock.PowerMock.expectNew;
import static org.powermock.api.easymock.PowerMock.replay;
import static org.powermock.api.easymock.PowerMock.verify;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.annotation.Mock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(UsesNewToInstantiateClass.class)
public class MockConstructorTest {

  @Mock
  private AnyOldClass anyClass;

  private UsesNewToInstantiateClass instance;

  @Test
  public final void testMockConstructor() throws Exception {

    instance = new UsesNewToInstantiateClass();

    expectNew(AnyOldClass.class).andReturn(anyClass);

    final String expected = "MY_OTHER_RESULT";
    expect(anyClass.someMethod()).andReturn(expected);

    replay(AnyOldClass.class, anyClass);
    String result = instance.createThing();
    verify(AnyOldClass.class, anyClass);
    assertEquals(expected, result);
  }

}

Firstly, this class has the usual PowerMock additions of:
@RunWith(PowerMockRunner.class)
@PrepareForTest(UsesNewToInstantiateClass.class)

at the top of the file plus the creation of the anyOldClass mock object. The important line of code to consider is:

    expectNew(AnyOldClass.class).andReturn(anyClass);

This line of code tells PowerMock to expect a call to new AnyOldClass() and return our anyClass mock object.

Also of interest are the calls to replay and verify. In the example above, they both have two arguments. The first, AnyOldClass.class relates to the expectNew(...) call above, whilst the second, anyClass refers to the straight forward mock call expect(anyClass.someMethod()).andReturn(expected);.

There are those times when you should really let new do what it does: create a new object of the requested type. There is a body of opinion that says you can over-isolate your code when testing and that mocking everything reduces the meaning and value of a test. To me there’s no right answer to this and it’s a matter of choice. It’s fairly obvious that if your code accesses an external resource such as a database, then you’d either refactor and implement DI or use PowerMock. If your code under test doesn’t access any external resources, then it’s more of a judgement call on how much code isolation is too much? This perhaps needs some thought and may be the subject for another blog on anther day...

 

From http://www.captaindebug.com/2011/10/using-powermock-to-mock-constructors.html

Dependency injection

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • What “The Rings of Power” Taught Me About a Career in Tech
  • Utilizing Database Hooks Like a Pro in Node.js
  • Browser Engines: The Crux of Cross-Browser Compatibility
  • Securing Cloud-Native Applications: Tips and Tricks for Secure Modernization

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: