4 Replies - 6195 Views - Last Post: 13 June 2009 - 04:18 AM Rate Topic: -----

#1 intelrate  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 11-June 09

How to mock protected method in Java

Post icon  Posted 11 June 2009 - 07:57 AM

Here is a question.

I wanted my JUnit tests to be more modular and found how to mock protected methods for that purpose. Briefly speaking, we cannot mock and control calls of protected method with JDK dynamic proxy because protected methods are not in any interface but we can create MockInterface with mock method under control and call it from overridden protected method to achieve our goal.

The problem Im trying to resolve now is that my mock method should have the same number of parameters as protected method I want to mock. It forces me to create several mock methods with different number of parameters which is not elegant. Does anyone know better solution in JMock or other Java framework? Any help would be very appreciated.

Is This A Good Question/Topic? 0
  • +

Replies To: How to mock protected method in Java

#2 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 2066
  • View blog
  • Posts: 4,299
  • Joined: 11-December 07

Re: How to mock protected method in Java

Posted 11 June 2009 - 04:18 PM

Maybe I'm missing something but what's wrong with this:

import static org.junit.Assert.*;

import org.junit.Test;


public class EinsteinFormulaTest {

	@Test
	public void testKineticEnergy() {

		final double restMass = 10.0;
		final double velocity = 100000000.0;
		final double expectedEnergy = 5.4601175017849928E16;
		final double mockRestEnergy = 8.987551787368178E17;

		EinsteinFormulaImpl einsteinFormula = new EinsteinFormulaImpl() {
			double energy(final double mass) {
				assertEquals(restMass, mass, 0.1);
				return mockRestEnergy;
			}
		};

		assertEquals(expectedEnergy, einsteinFormula.kineticEnergy(
				restMass, velocity), 0.0000001);
	}
}



This post has been edited by cfoley: 11 June 2009 - 04:19 PM

Was This Post Helpful? 0
  • +
  • -

#3 ericode  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 112
  • Joined: 09-December 06

Re: How to mock protected method in Java

Posted 12 June 2009 - 06:43 PM

View Postcfoley, on 11 Jun, 2009 - 03:18 PM, said:

Maybe I'm missing something but what's wrong with this:

import static org.junit.Assert.*;

import org.junit.Test;


public class EinsteinFormulaTest {

	@Test
	public void testKineticEnergy() {

		final double restMass = 10.0;
		final double velocity = 100000000.0;
		final double expectedEnergy = 5.4601175017849928E16;
		final double mockRestEnergy = 8.987551787368178E17;

		EinsteinFormulaImpl einsteinFormula = new EinsteinFormulaImpl() {
			double energy(final double mass) {
				assertEquals(restMass, mass, 0.1);
				return mockRestEnergy;
			}
		};

		assertEquals(expectedEnergy, einsteinFormula.kineticEnergy(
				restMass, velocity), 0.0000001);
	}
}




I'm assuming the problem with that is that you have to create a new energy method for each energy method there is in the class you're trying to mock (I know there was only one in the example website, but you could imagine there being a bunch of overloaded methods with the same name and return type).

Truth be told, I have never used the mock object frameworks so I started looking into it this afternoon, and found a lot of cool stuff. One of the coolest things was the Javassist library.

I downloaded their jar and started trying it out. Maybe I went off on a tangent from what intelrate was thinking of, but check out this code I just made.

/*
Testing out the reification provided by
the javassist library (http://www.csg.is.titech.ac.jp/~chiba/javassist/).
We'll create a class at runtime, and dynamically add some methods to it.

javac -classpath .;javassist.jar Test.java
java -classpath .;javassist.jar Test

output:
Values from getSomeValue methods:
        original
        original
        original
        original
Values from getSomeValue methods:
        changed
        changed
        changed
        changed
*/

import javassist.*;

public class Test
{
	public static void main(String[]args) throws Exception
	{
		//let's pretend Junk (defined below) is the class we want to mock
		Junk originalJunk = new Junk();
		testJunk(originalJunk);

		ClassPool pool = ClassPool.getDefault();

		CtClass superClass = pool.get("Junk");

		CtClass mockedSubClass = pool.makeClass("NewJunk");
		mockedSubClass.setSuperclass(pool.get("Junk"));

		//we want to change every single getSomeValue method to return a different constant
		for(CtMethod method : superClass.getDeclaredMethods())
		{
			if(method.getName().equals("getSomeValue"))
			{
				CtMethod overriddenMethod = new CtMethod(method, mockedSubClass, null);
				overriddenMethod.setBody("return \"changed\";");
				mockedSubClass.addMethod(overriddenMethod);
			}
		}

		Junk mockObject = (Junk) (mockedSubClass.toClass().newInstance());
		testJunk(mockObject);
	}//main

	public static void testJunk(Junk j)
	{
		System.out.println("Values from getSomeValue methods:");
		System.out.println("\t" + j.getSomeValue());
		System.out.println("\t" + j.getSomeValue(3, ""));
		System.out.println("\t" + j.getSomeValue(3.0, 4));
		System.out.println("\t" + j.getSomeValue("", 1));
	}//testJunk
}//class Test


class Junk
{
	//I needed to create this constructor because I had a
	//problem with creating an instance using the .newInstance()
	//method for the subclass
	public Junk(){}

	protected String getSomeValue()					{return "original";}
	protected String getSomeValue(int n, String s)	{return "original";}
	protected String getSomeValue(double n, int p)	{return "original";}
	protected String getSomeValue(String n, int p)	{return "original";}
}//class Junk


Was This Post Helpful? 0
  • +
  • -

#4 intelrate  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 11-June 09

Re: How to mock protected method in Java

Posted 13 June 2009 - 04:10 AM

View Postcfoley, on 11 Jun, 2009 - 03:18 PM, said:

Maybe I'm missing something but what's wrong with this...


Thanks, this was a good try :) but your test doesn't force 'energy' method to be called from 'kineticEnergy'.

Using JMock we specify expectation and if call didn't happen test fails.
Was This Post Helpful? 0
  • +
  • -

#5 intelrate  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 11-June 09

Re: How to mock protected method in Java

Posted 13 June 2009 - 04:18 AM

Quote

Truth be told, I have never used the mock object frameworks so I started looking into it this afternoon, and found a lot of cool stuff.


Wow! Changing a body of method gives powerful abilities. This library is quite verbose though.

Nevertheless, thanks - studied something new :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1