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
  1. DZone
  2. Coding
  3. Languages
  4. Mocking Static Methods in Groovy

Mocking Static Methods in Groovy

Geraint Jones user avatar by
Geraint Jones
·
Apr. 15, 13 · Interview
Like (4)
Save
Tweet
Share
83.47K Views

Join the DZone community and get the full member experience.

Join For Free

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, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Fixing Bottlenecks in Your Microservices App Flows
  • DevOps vs Agile: Which Approach Will Win the Battle for Efficiency?
  • A Guide to Understanding XDR Security Systems
  • 10 Things to Know When Using SHACL With GraphDB

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: