Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

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
Avatar of girionis
girionis
Flag of Greece image

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.
Avatar of gudii9

ASKER

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
The mock subscriber is the class that should receive the event, so it "subscribes" to the expectations.
Avatar of gudii9

ASKER

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
Avatar of gudii9

ASKER

I there is a place to download the code. Please advise
Avatar of gudii9

ASKER

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
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.
Avatar of gudii9

ASKER

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?
This is the link to download jmock.

Yes you can run it in eclipse.
Avatar of gudii9

ASKER

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
Avatar of gudii9

ASKER

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
You only need to add the three mentioned files, not all of them.
Avatar of gudii9

ASKER

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?
Avatar of gudii9

ASKER

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
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.
Avatar of gudii9

ASKER

Does not mock work with abstract or concrete classes. Does mock only work with interfaces? Why it is so?
Avatar of gudii9

ASKER

publisher.add((Subscriber) mockSubscriber.proxy());


what is the meaning of above line. I am not clear. please advise
Avatar of gudii9

ASKER

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
ASKER CERTIFIED SOLUTION
Avatar of girionis
girionis
Flag of Greece image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

I am facing display issue when i open above link in chrome. Text lines kind of cutting to half to read completely. please advise