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
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Graceful Shutdown: Spring Framework vs Golang Web Services
  • Actuator Enhancements: Spring Framework 6.2 and Spring Boot 3.4
  • Implementing Exponential Backoff With Spring Retry
  • Structured Logging in Spring Boot 3.4 for Improved Logs

Trending

  • Introducing senro: A Pipeline Engine You Program in Go
  • The Context Window Trap: Why More Context Doesn’t Mean Better AI
  • Nobody Designs an RBAC Mess; Everyone Ends Up With One
  • Beyond @Transactional: Solving the Dual-Write Problem in Distributed Microservices

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Frameworks
  4. @Autowired + PowerMock: Fixing Some Spring Framework Misuse/Abuse

@Autowired + PowerMock: Fixing Some Spring Framework Misuse/Abuse

Unfortunately, I have seen it misused several times when a better design would be the solution.

By 
Alied Pérez
·
Nov. 19, 13 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
30.7K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

Every time I see PowerMock as a test dependency I tend to get nervous. Don't get me wrong; PowerMock is a great library and does great work. I just have a problem with people who abuse it. I don't doubt there are many scenarios where it will be very useful; however, I have yet to actually find one in my Real World(TM) job. Unfortunately, I have seen it misused several times when a better design would be the solution.

One way I have seen it used is with Spring @Autowired in private fields. Of all ways to use Spring DI, this is the worst. You cannot properly test; you depend on Spring to fully populate your class, and you cannot reuse your class without carrying the whole Spring framework.

I was once working on a project with lots of classes like this:

public class Client {
  @Autowired
  private Service service;

  public void doSomething() {
    service.doServiceStuff();
  }

}

Being private fields, there is no correct way to set them outside Spring. You will need to use Reflection or some sort of black magic.

The developers opted to use PowerMock:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Client.class })
public class ClientTest {

  @InjectMocks
  private Client client= new Client();
  @Mock
  private Service service;

  @Test
  public void doSomethingTest {
    //setup test data
    client.doSomething();
  }
}

They decided to add a new dependency and make the code even more complicated. I then refactored it like this:

public class Client {

  private Service service;

 @Autowired
 public Client(final Service service) {
    //check preconditions
    this.service = service;
  }

  public void doSomething() {
    service.doServiceStuff();
  }
}

Now it is clear what this class depends on, and you cannot instantiate it (directly or indirectly) without the required dependencies (you will appreciate this when you have some nasty NPEs in production because someone added a new @Autowired private field). Not to mention we got rid of an unneeded dependency.

And the test looked like this:

@RunWith(MockitoJUnitRunner.class)
public class ClientTest {

  @Mock
  private Service service;

  @Test
  public void doSomethingTest {
    //setup test data
    final Client client= new Client(service);
    client.doSomething();
    //assertions and verifications
  }
}

It is unfortunate that frameworks like Spring, otherwise very useful, are so easily misused (should I say abused?) by people who don't take the time to analyze the problem at hand. Maybe a good framework should not be that powerful? Or maybe going the not preferred way should be tedious and effort consuming? I would like to know your opinions about this.

Soon I'll be posting more magic with PowerMock to fix a bad design.

Spring Framework Framework

Opinions expressed by DZone contributors are their own.

Related

  • Graceful Shutdown: Spring Framework vs Golang Web Services
  • Actuator Enhancements: Spring Framework 6.2 and Spring Boot 3.4
  • Implementing Exponential Backoff With Spring Retry
  • Structured Logging in Spring Boot 3.4 for Improved Logs

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook