The Artima Developer Community
Sponsored Link

Java Buzz Forum
Using JMock with Scala

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Lalit Pant

Posts: 51
Nickname: litan
Registered: Jun, 2007

Lalit Pant is a freelance programmer based out of Dallas, Texas
Using JMock with Scala Posted: Dec 5, 2007 9:54 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Lalit Pant.
Original Post: Using JMock with Scala
Feed Title: All Things Runnable / Java
Feed URL: http://feeds.feedburner.com/lalitpant/java
Feed Description: Java related posts on Lalit Pant's Blog
Latest Java Buzz Posts
Latest Java Buzz Posts by Lalit Pant
Latest Posts From All Things Runnable / Java

Advertisement
While working on the Java version of Jiva earlier this year, I used JMock pretty heavily to test all of the non-deterministic code that is integral to the workings of a Genetic Algorithm.

When I ported Jiva to Scala, I did not really know if I could continue to use JMock for my testing needs. As it turned out, JMock worked out very well for testing Scala code.

I could go in and try to explain some of the ways in which JMock is used within Jiva, but I'm afraid that will introduce a lot of Genetic Algorithms related terminology, and will potentially divert attention from the main point of this post. So I will instead demonstrate the usage of JMock with Scala via a very simple (and contrived) example. If you want to see JMock in action within Jiva, you are welcome to browse the Subversion repository for the project:
http://jiva-ng.googlecode.com/svn/trunk/src/test/scala/net/xofar/jiva/operators/

Back to the simple example...

Let's say we have a Class-under-test (Cut) in our code, and a Helper class that is used by Cut:

class Helper {
def help = "helpfulResult"
def helpWith(problem: String) = problem + " whatever help for String problem"
def helpWith(problem: int) = problem + " whatever help for int problem"
}

class Cut(helper: Helper) {
def doWork: String = {
helper.help + " processed"
}

def doWork(problem: String): String = {
helper.helpWith(problem) + " str processed"
}

def doWork(problem: int): String = {
helper.helpWith(problem) + " int processed"
}
}

The Helper class has three different helper methods with different signatures. Cut also has three methods that delegate to the corresponding Helper methods. The idea here is that we want to test the Cut class by mocking out the helper used by Cut.

Let's jump right into the Test class (you will need to enable Java generics support in Scala for this to work; more on that later):

import junit.framework.TestCase
import junit.framework.Assert._

import org.jmock.Mockery
import org.jmock.lib.legacy.ClassImposteriser
import net.xofar.jiva.util.mock.SExpectations
import org.jmock.Expectations._

class TestCut extends TestCase {

val context = new Mockery() {
{
// we want to be able to mock classes
setImposteriser(ClassImposteriser.INSTANCE);
}
};

def test1 = {
// create the mock
val helper = (context.mock(classOf[Helper])).asInstanceOf[Helper]

// setup mock return values
val noOpHelpReturn = "mockHelp"
val strHelpReturn = "mockHelp stringResult"
val intHelpReturn = "mockHelp intResult"

// set Expectations
context.checking(
new SExpectations() {{
one(helper).help
will(returnValue(noOpHelpReturn));

exactly(1).of(helper).helpWith(withArg(any(classOf[String])))
will(returnValue(strHelpReturn));

atLeast(1).of(helper).helpWith(withArg(any(classOf[int])))
will(returnValue(intHelpReturn));
}
})

// setup the class under test with the mock
val cut = new Cut(helper)


// exercise the class under test
// and verify results
val result = cut.doWork
assertEquals(result, noOpHelpReturn + " processed")

val result2 = cut.doWork("task")
assertEquals(result2, strHelpReturn + " str processed")

val result3 = cut.doWork(3)
assertEquals(result3, intHelpReturn + " int processed")

// make sure that the expectations on the mock were satisfied
context.assertIsSatisfied
}
}
This should be pretty straightforward for those of you who are familiar with JMock, except for a couple of things:
  • We set up Expectations using something called SExpectations.
  • We specify method paramater expectations using a method called withArg, as opposed to the more familiar with method provided by JMock
Both of these items are driven by the same reason: with is a reserved word in Scala. To get around this, I created a subclass of Expectations:

package net.xofar.jiva.util.mock;

import org.hamcrest.Matcher;
import org.jmock.Expectations;

public class SExpectations extends Expectations {
public <T> T withArg(Matcher<T> matcher) {
return super.with(matcher);
}
}
SExpectations provides a method called withArg that just calls into the standard with method provided within its superclass by JMock. So essentially this class functions as an adapter that allows JMock parameter matching to be used by code written in Scala.

That's about it, actually. To reiterate: if you know how to use JMock (with Java), it should be pretty straightforward for you to start using it with Scala.

Some additional comments:
  • To work with JMock, you need to use Scala with the -Ygenerics and -target:jvm-1.5 options.
  • I used JUnit 3 for my Scala unit tests because the Scala Eclipse plugin does not quite support annotations. The standalone/command-line version of Scala supports annotations just fine, so it should be very possible to use JMock/JUnit 4 with Scala
  • I suppose I could have used MockObjectTestCase as a base class for my Tests. I just wanted to have more control over things as I worked through the Scala/JMock integration
  • I used the CGLib based Legacy ClassImposteriser because I needed to mock system classes for testing Jiva code
  • Versions used - Scala: 2.6.0, JMock: 2.4.0

Read: Using JMock with Scala

Topic: Finding more Almaers Previous Topic   Next Topic Topic: Interactive (Web) Application Architecture Patterns

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use