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
11 Monitoring and Observability Tools for 2023
Learn more
  1. DZone
  2. Coding
  3. Languages
  4. Mocking a Hessian Web Service Using Groovy

Mocking a Hessian Web Service Using Groovy

Victor Savkin user avatar by
Victor Savkin
·
Feb. 25, 11 · Interview
Like (0)
Save
Tweet
Share
8.67K Views

Join the DZone community and get the full member experience.

Join For Free

During last month there were a lot of moments when I thought: ‘How cool it is that I can use Groovy to write it’. For instance, I was working on mocking a hessian web service a few days ago. Hessian is binary web service protocol and writing a mock web service might have been a tricky task. At least I though so in the beginning. But it turned out that everything can be done in a clear and neat way if you have right tools. To show how I used Groovy to do it let’s take a very simple interface that has a hessian based implementation:

interface SampleHessianService {
    String sayHi(String m)
}

Our goal is to write an utility class mocking this service so we can write integration tests for our client (for example, a web app). The client of the service uses such a chunk of code to access the service:

def factory = new HessianProxyFactory()
def client = factory.create(SampleHessianService, "http://localhost:8080/sample")
String response = client.sayHi('John')

To write my mock service in old Java world I would write something like this:

public class MyServlet extends HessianServlet implements SampleHessianService {
    Object mockObject

    public String sayHi(String m){
        ....
        //somehow delegate this call to mockObject 
        ....
    }
}

MyServlet servlet = new MyServlet();
//creating a jetty server, creating a jetty context
context.addServlet(new ServletHolder(servlet), "/sample");
//starting the jetty server

There are a few things that bother me in this approach. If the interface had like 20 methods I would have to implement all of them to delegate all the work to my mockObject. But I don’t work to write this kind of stuff every time I need a Hessian service. Ideally, I would like to pass a Spock mock object (or any other mock object) to generate a Hessian servlet.

The first feature of Groovy I tried to use to improve my old java style version is @Delegate. @Delegate annotation implements all the methods of SampleHessianService for me and delegates all the calls to a specified object:

    class SampleHessianService_HessianImpl extends HessianServlet {
        @Delegate SampleHessianService delegate
    }
    def hessian = new SampleHessianService_HessianImpl()
    hessian.delegate = Mock(SampleHessianService)

It looks much better, doesn’t it? But I still need to write this dummy class. Writing boilerplate code is OK in Java but not in Groovy. So the next step I took was generating SampleHessianService_HessianImpl in runtime:

    def type = SampleHessianService
    def fullName = type.name
    def className = type.simpleName

    def classText = """
        import com.caucho.hessian.server.HessianServlet
        class ${className}_HessianImpl extends HessianServlet {
            @Delegate ${fullName} delegate
        }
    """
    def gcl = new GroovyClassLoader()
    def clazz = gcl.parseClass(classText)
    def res = clazz.newInstance()

There is one thing I don’t like in generators: I have to add an additional step to my build process to do it. But not in Groovy. Using GroovyClassLoader you can parse new classes easily in runtime without any additional steps. Cool.

The result of my work is this very small but useful class:

class HessianServletFactory {

    HessianServlet createHessianServlet(Map args) {
        assert args.type instanceof Class, 'type parameter is not passed or is not a class'
        assert args.delegate, 'delegate parameter is not passed'

        def classText = genClassText(args.type)

        def gcl = new GroovyClassLoader()
        def clazz = gcl.parseClass(classText)
        def res = clazz.newInstance()
        res.delegate = args.delegate
        return res
    }

    private genClassText(type){
        def fullName = type.name
        def className = type.simpleName

        """
            import com.caucho.hessian.server.HessianServlet
            class ${className}_HessianImpl extends HessianServlet {
                @Delegate ${fullName} delegate
            }
        """
    }
}

The way you can use it in your test:

@Mixin(HessianServletFactory)
class HessianServletSpec extends Specification {

    def 'should create a hessian servlet using a type and a spock mock object'() {
        setup: 'setting up server part'
        def service = createHessianServlet(type: SampleHessianService, delegate: Mock(SampleHessianService))
        //adding it to jetty, starting jetty

        and: 'setting up client part'
        def factory = new HessianProxyFactory()
        def client = factory.create(SampleHessianService, "http://localhost:8080/sample")

        when:
        def response = client.sayHi(NAME)

        then:
        service.delegate.sayHi(NAME) >> RESPONSE
        response == RESPONSE

        where:
        NAME = 'John'
        RESPONSE = 'Hi John'
    }
}

As you can see mocking a hessian servlet using HessianServletFactory is easy. You don’t have to create new classes each time you want to do it, you don’t have to add an additional step to your build process. The only thing you have to do is to specify a type and a delegate. It can be a Spock mock object or just a fake implementation. Also, I’ve used Mixin in my test because the factory doesn’t have any state and I have not wanted to create a dummy receiver: new HessianServletFactory().createHessianServlet(...) I could use a static method here too. But I prefer never use static methods unless it is a one line method that just creates an object.

 

From http://victorsavkin.com/post/3473984162/mocking-a-hessian-web-service-using-groovy

Web Service Hessian (Web service protocol) Groovy (programming language)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How To Handle Secrets in Docker
  • JWT Authentication and Authorization: A Detailed Introduction
  • 3 Main Pillars in ReactJS
  • A Beginner's Guide to Infrastructure as Code

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: