• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 552
  • Last Modified:

junit mock object

Hi,

I am looking for a simple example on junit using mock object. I read about EasyMock which is interesting. I want simple complete example on writing simple java application and writing unit test for that by using mock objects. Please advise
0
gudii9
Asked:
gudii9
  • 13
  • 7
1 Solution
 
girionisCommented:
My personal framework for mocking objects is jmock. Here is a complete example

import org.jmock.*;

class PublisherTest extends MockObjectTestCase {
    public void testOneSubscriberReceivesAMessage() {
        // set up
        Mock mockSubscriber = mock(Subscriber.class);
        Publisher publisher = new Publisher();
        publisher.add((Subscriber) mockSubscriber.proxy());
        
        final String message = "message";
        
        // expectations
        mockSubscriber.expects(once()).method("receive").with( eq(message) );
        
        // execute
        publisher.publish(message);
    }
}

Open in new window


Taken from here.
0
 
gudii9Author Commented:
Why they used Mock subscriber object rather than mock Publisher object. Since publisher publishing first I thought creating publisher mock object would be good idea.


I have not clearly understood below line

mockSubscriber.expects(once()).method("receive").with( eq(message) );

can you please explain.

Please advise
0
 
girionisCommented:
The mock subscriber is the class that should receive the event, so it "subscribes" to the expectations.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
gudii9Author Commented:
I was trying example in the link
http://jmock.org/getting-started.html

I see below jars needed
To use jMock 2.6.0 you must add the following JAR files to your class path:

jmock-2.6.0.jar
hamcrest-core-1.3.jar
hamcrest-library-1.3.jar

I went to below site to download them

http://www.java2s.com/Code/Jar/j/Downloadjmock260RC2jar.htm


I do not see
jmock-2.6.0.jar

instead i see
jmock-2.6.0-RC1.jar

Can i use jmock-2.6.0-RC1.jar instead?

what is the difference between above two jars. please advise
0
 
gudii9Author Commented:
I there is a place to download the code. Please advise
0
 
gudii9Author Commented:
When i tried to run getting error as attached

My code looks like

import org.jmock.*;

class PublisherTest extends MockObjectTestCase {
    public void testOneSubscriberReceivesAMessage() {
        // set up
        Mock mockSubscriber = mock(Subscriber.class);
        Publisher publisher = new Publisher();
        publisher.add((Subscriber) mockSubscriber.proxy());
       
        final String message = "message";
       
        // expectations
        mockSubscriber.expects(once()).method("receive").with( eq(message) );
       
        // execute
        publisher.publish(message);
    }
}



other class is

public class MockObjectTestCase {

}


other class is


public class Publisher {

}


other class is
interface Subscriber {
    void receive(String message);
}

I do not see complete example code in this link. Please advise how can i fix so that i can execute this junit program
JMockErr.jpg
0
 
girionisCommented:
You need to include all relevant jars in your classpath.

jmock-2.6.0.jar
hamcrest-core-1.3.jar
hamcrest-library-1.3.jar

If you downloaded jmock all of these should be in the place where you unzipped jmock.
0
 
gudii9Author Commented:
downloaded jmock

what is the link to download it. Please advise

http://powerdream5.wordpress.com/2007/10/16/an-example-of-jmock/

can i  run above example in eclipse?
0
 
girionisCommented:
This is the link to download jmock.

Yes you can run it in eclipse.
0
 
gudii9Author Commented:
import org.jmock.*;

class PublisherTest extends MockObjectTestCase {
    public void testOneSubscriberReceivesAMessage() {
        // set up
        Mock mockSubscriber = mock(Subscriber.class);
        Publisher publisher = new Publisher();
        publisher.add((Subscriber) mockSubscriber.proxy());
        
        final String message = "message";
        
        // expectations
        mockSubscriber.expects(once()).method("receive").with( eq(message) );
        
        // execute
        publisher.publish(message);
    }
}

Open in new window



i do not see all relevant code for Publisher Subscriber, extending class etc.

Can you please point me if there is link to download entire source to run this example. is this example working for you, Can you please post complete source code of all dependent classes as well
0
 
gudii9Author Commented:
I have copied all the jars in my eclipse project then i went to build path and 'add jars'. I still see the error as attached. Please advise
JunitErr4.jpg
JunitErr3.jpg
0
 
girionisCommented:
You only need to add the three mentioned files, not all of them.
0
 
gudii9Author Commented:
Which three?
All empty files?

I see the code in the link as follows



one interface is
interface Subscriber {
    void receive(String message);
}

one class is
import org.jmock.*;

class PublisherTest extends MockObjectTestCase {
    public void testOneSubscriberReceivesAMessage() {
    }
}




Mock mockSubscriber = mock(Subscriber.class);
Publisher publisher = new Publisher();
publisher.add( (Subscriber)mockSubscriber.proxy() );

final String message = "message";




other class is

import org.jmock.*;

class PublisherTest extends MockObjectTestCase {
    public void testOneSubscriberReceivesAMessage() {
        // set up
        Mock mockSubscriber = mock(Subscriber.class);
        Publisher publisher = new Publisher();
        publisher.add((Subscriber) mockSubscriber.proxy());
       
        final String message = "message";
       
        // expectations
        mockSubscriber.expects(once()).method("receive").with( eq(message) );
       
        // execute
        publisher.publish(message);
    }
}



Nothing else i can find there as per the code . please advise. I wonder why i get error at extends class also at Mock class. Can you please show the structure of project screenshot including the added jars?
0
 
gudii9Author Commented:
Do I supposed to create method like this(eclipse generated which does not see right to me)

      private Mock mock(Class<Subscriber> class1) {
            // TODO Auto-generated method stub
            return null;
      }

I am not very clear on below lines

 // expectations
        mockSubscriber.expects(once()).method("receive").with( eq(message) );

 Mock mockSubscriber = mock(Subscriber.class);

Please advise
0
 
girionisCommented:
No you don't need to create a Mock Object. You should mock the object you want to test. You can find a step-by-step example here.
0
 
gudii9Author Commented:
Does not mock work with abstract or concrete classes. Does mock only work with interfaces? Why it is so?
0
 
gudii9Author Commented:
publisher.add((Subscriber) mockSubscriber.proxy());


what is the meaning of above line. I am not clear. please advise
0
 
gudii9Author Commented:
package eePackage;

interface Appender
{
    /**
     * Appends an integer value to the end of the string.
     * @param value the integer value to be appended.
     * @return the string with the appended value.
     */
    String append(final Integer value);
}






package eePackage;

interface Calculator
{
    /**
     * Multiplies two integer values and returns the result.
     * @param a the first value.
     * @param b the second value.
     * @return the product of the multiplication.
     */
    Integer multiply(final int a, final int b);
}





package eePackage;

public interface Reverser
{
    /**
     * Reverses a string.
     * @param toBeReversed the string to be reversed.
     * @return the reversed string.
     */
    String reverse(String toBeReversed);
}





package eePackage;

public class Computer
{
    private Calculator calculator;
    private Appender appender;
    private Reverser reverser;
 
    /**
     * Constructor.
     *
     * @param calculator the calculator class.
     * @param appender the appender class.
     * @param reverser the reverser class.
     */
    public Computer(final Calculator calculator, final Appender appender, final Reverser reverser)
    {
        this.calculator = calculator;
        this.appender = appender;
        this.reverser = reverser;
    }
   
    public String compute(final int a, final int b)
    {
        Integer product = calculator.multiply(a, b);
        return "";
    }
}






package eePackage;

import org.jmock.Expectations;
import org.jmock.Mockery;

import junit.framework.TestCase;

public class ComputerTest extends TestCase
{
    private Mockery mockery;
    private Calculator calculator;
    private Appender appender;
    private Reverser reverser;
    private Computer computer;
 
    /**
     * {@inheritDoc}
     */
    @Override
    public void setUp()
    {
        mockery = new Mockery();
        calculator = mockery.mock(Calculator.class);
        appender = mockery.mock(Appender.class);
        reverser = mockery.mock(Reverser.class);
 
        computer = new Computer(calculator, appender, reverser);
    }
 
    /**
     * Tests the compute method.
     */
    public void testCompute()
    {
        final Integer product = Integer.valueOf(200);
        final int a = 10, b = 20;
        final String someString = "a string ";
     
        mockery.checking(new Expectations(){
            {
                one(calculator).multiply(a, b);
                will(returnValue(product));
     
                one(appender).append(product);
                String appendedString = someString + product.toString();
                will(returnValue(appendedString));
     
                one(reverser).reverse(appendedString);
            }
     
        });
     
        computer.compute(a, b);
        mockery.assertIsSatisfied();
    }
}




I tried the example from link

http://thejavablog.wordpress.com/2008/05/27/testing-with-jmock/


My tests are failing with red color with below error.


not all expectations were satisfied
expectations:
  expected once, already invoked 1 time: calculator.multiply(<10>, <20>); returns <200>
  ! expected once, never invoked: appender.append(<200>); returns "a string 200"
  ! expected once, never invoked: reverser.reverse("a string 200"); returns a default value
what happened before this:
  calculator.multiply(<10>, <20>)

      at org.jmock.api.ExpectationError.notAllSatisfied(ExpectationError.java:27)
      at org.jmock.Mockery.assertIsSatisfied(Mockery.java:199)
      at eePackage.ComputerTest.testCompute(ComputerTest.java:54)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      at java.lang.reflect.Method.invoke(Unknown Source)
      at junit.framework.TestCase.runTest(TestCase.java:176)
      at junit.framework.TestCase.runBare(TestCase.java:141)
      at junit.framework.TestResult$1.protect(TestResult.java:122)
      at junit.framework.TestResult.runProtected(TestResult.java:142)
      at junit.framework.TestResult.run(TestResult.java:125)
      at junit.framework.TestCase.run(TestCase.java:129)
      at junit.framework.TestSuite.runTest(TestSuite.java:255)
      at junit.framework.TestSuite.run(TestSuite.java:250)
      at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:131)
      at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)



Why author declared three interfaces and passed them as the class level variables to Computer.jav class.

What is the code flow in the ComputerTest.java. Please advise
ComputerTestErr.jpg
0
 
girionisCommented:
First of all, you are right, jmock only works with interfaces. You cannot mock concrete or abstract classes.

These errors

! expected once, never invoked: appender.append(<200>); returns "a string 200"
  ! expected once, never invoked: reverser.reverse("a string 200"); returns a default value

mean that you expect some calls to happen but they never happen in your code. Do you call these? Have you followed the tutorial step by step?
0
 
gudii9Author Commented:
I am facing display issue when i open above link in chrome. Text lines kind of cutting to half to read completely. please advise
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 13
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now