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

  • The Unreasonable Effectiveness of the Actor Model for Creating Agentic LLM Applications
  • Why and How To Integrate Elastic APM in Apache JMeter
  • Transitioning From Groovy to Kotlin for Gradle Android Projects
  • Streamlining Your Workflow With the Jenkins HTTP Request Plugin: A Guide to Replacing CURL in Scripts

Trending

  • Closing the Drift Loop: An AI Agent That Drafts Terraform Fixes
  • Genkit Flows as senro Steps: Extremely Powerful AI Pipelines in Go
  • Why Kotlin or Java Is the Wrong Question For Enterprises
  • When RabbitMQ Accepts a Message but Does Not Route It to a Queue

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. Languages
  4. Mocking Static Methods in Groovy

Mocking Static Methods in Groovy

By 
Geraint Jones
·
Apr. 15, 13 · Interview
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
93.5K 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

Using Groovy to test not only other Groovy classes but also Java classes is an increasing popular approach given frameworks like Spock which facilitate Test Driven and Behaviour Driven Development.

A common problem when testing though is having to deal with legacy code and more often than not having to mock static methods calls. When writing tests in Groovy, the approach to mocking static calls will depend on the type of class you're testing and what type of class has the static method in.

If the Groovy class you're testing makes calls a static method on another Groovy class, then you could use the ExpandoMetaClass which allows you to dynamically add methods, constructors, properties and static methods. The below Account Groovy class has a static method called getType(). The Customer Groovy class you're trying to test calls the getType() static method within it's getAccountType() method:

class Customer {
 
 String getAccountType() {
  return Account.getType();
 }
  
}
 
class Account {
 
 static String getType() {
  return "Personal";
 }
 
}
 
class CustomerTest extends GroovyTestCase {
  
 void testGetAccountType() {
   
  Customer cust = new Customer()
  assert cust.getAccountType() == "Personal"
 
  Account.metaClass.static.getType = {return "Business"}
   
  assert cust.getAccountType() == "Business"
     
 }
 
}

The CustomerTest Groovy class shows how the getType static method can be overridden using the metaClass property. This isn't strictly mocking, more dynamically changing a class. An alternative approach is to use Spock's GroovyMock to achieve a similar result. (A more detailed description of Spock's mocking and stubbing features can be found here:)

import spock.lang.*
 
class CustomerTest extends Specification {
  
 def "get account type"() {
    
  setup: 
   GroovyMock(Account, global: true)
   Account.getType() >> "Business"
   Customer cust = new Customer()
   
  when: "obtaining a customer's account type"
   def type = cust.getAccountType()
 
  then: "the type will be a Business account"
   type == "Business"
     
 }
 
}

If the Account class is a Java not Groovy class then we can still mock it out using the above methods. The problem with mocking Java static methods though, when using Groovy for testing, is when they are called from Java classes and these calling classes are the ones you are trying to test.

For example, if we now have a Customer Java class and also an Account Java class, and a CustomerTest Groovy class, the ExpandoMetaClass and GroovyMock approaches will not work globally but will work locally. The below CustomerTest will pass.

public class Customer {
 
 public String getAccountType() {
  return Account.getType();
 }
  
}
 
public class Account {
 
 public static String getType() {
  return "Personal";
 }
 
}
class CustomerTest extends GroovyTestCase {
  
 void testGetAccountType() {
   
  Customer cust = new Customer()
  assert cust.getAccountType() == "Personal"
 
  Account.metaClass.static.getType = {return "Business"}
   
  assert Account.getType() == "Business"
  assert cust.getAccountType() == "Personal"
     
 }
 
}

The way around this is to use a mocking framework like Powermock or JMockit. The below amended CustomerTest Groovy class shows how Powermock can be integrated into a GroovyTestCase:

import groovy.mock.interceptor.*
import org.powermock.api.mockito.PowerMockito;
import static org.mockito.Mockito.*;
import org.powermock.core.classloader.annotations.PrepareForTest
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner
 
@RunWith( PowerMockRunner.class )
@PrepareForTest(Account.class)
class CustomerTest extends GroovyTestCase {
  
 public void testGetAccountType() { 
   
  Customer cust = new Customer()
  assert cust.getAccountType() == "Personal"
 
  PowerMockito.mockStatic(Account.class);
  when(Account.getType()).thenReturn("Business");
     
  assert cust.getAccountType() == "Business"
  
 }
 
}


Using Mockito's when to mock the return value of the static getType() call enables "Business" to be returned instead of "Personal". This example shows how when writing Groovy tests to test Java classes, using a framework like Powermock can fill the void of mocking Java static methods when called from the Java classes you are trying to test.

Groovy (programming language)

Published at DZone with permission of Geraint Jones. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • The Unreasonable Effectiveness of the Actor Model for Creating Agentic LLM Applications
  • Why and How To Integrate Elastic APM in Apache JMeter
  • Transitioning From Groovy to Kotlin for Gradle Android Projects
  • Streamlining Your Workflow With the Jenkins HTTP Request Plugin: A Guide to Replacing CURL in Scripts

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