zur Startseite


 Home
 Contact
+MockCreator
+Competence
+Projects
 XPedition german content
 Feedback


 deutschenglish



download zip      deutscher Text

July 2003 MockCreator has moved to SourceForge. New Releases will only be available there.

Mock Creator was originally developed by Christian Junghans at abstrakt. It is used to generate Mockobjekts from Java Interfaces. MockCreator is available for

"older" News

26. August 2002
Feature-Release for Eclipse:
Class files even out of jars can be used to generate MockObjects.
Bugfix-Release for all Versions:
Multi-dimensional arrays in parameters and return values are now generated correctly.

12. August 2002
Bugfix-Release for Eclipse. The GUI can be resized now to make long package names visible.

08. August 2002
Bugfix-Release for Eclipse. Will now work correctly for projects not located under ECLIPSE_HOME/workspace

MockCreator is free software, we don't grant any warranty for problems resulting from the use of the Mock Creator.

Mailing List

We have setup a mailinglist on sourceforge. Please use this list for feedback and bugreports.

We are looking forward to people contributing their favorite IDE-integrationen. If you like, please help us fixing the next known issues and bugs..

What is a MockObject?

MockObjects are components used for Unit-Test. They simulate further objects or subsystems to be used in a TestCase.

This article covers only usage of the MockCreator. It does not cover MockObjects at all. Please refer to www.mockobjects.com for this introduction.

Interface of generated MockObjekte

This is a example for the interface Foo:

public interface Foo {
  String doSomething( String something );
  double squareRoot( double input );
}

This is the generated MockImplementation:

public class MockFoo extends de.abstrakt.mock.MockObject implements Foo {
  // Methods from Foo
  public String doSomething( java.lang.String something )  {...}
  public double squareRoot( double input )  {...}

  // setup MockObject: set expectations,
  // if needed include returnvalue or exception to be thrown.
  public void expectDoSomething( String something, String returnValue )  {...}
  public void expectDoSomething( String something, Throwable throwable )  {...}
  public void expectSquareRoot( double input, double returnValue ) {...}
  public void expectSquareRoot( double input, Throwable throwable )  {...}

  // setup MockObject: don't care for the named methods.
  // if needed including return value or exception to be thrown.
  public void setDoSomethingDummy( Throwable throwable )  {...}
  public void setDoSomethingDummy( String returnValue )  {...}
  public void setSquareRootDummy( Throwable throwable )  {...}
  public void setSquareRootDummy( double returnValue )  {...}
}

Important inherited methods from de.abstrakt.mock.MockObject:

package de.abstrakt.mock;
public class MockObject {
  public void startBlock()  {...}
  public void endBlock()  {...}
  public void verify()  {...}
  public Boolean checkDummy( Boolean flag, boolean value )  {...}
  [...]
}

Simple Features

MockCreator generates Mockobjekts, that implement the chosen interface. This paragraph describes a TestCase that expects

  • the method doSomething on a Foo-object to be called with parameter "nobody expects"
  • this call should return "the spanish inquisition".

If squareRoot(...) be called (or doSomething() with another parameter), MockFoo should throw an exception.

// setup of MockObjects
MockFoo mockFoo = new MockFoo();
mockFoo.expectDoSomething( "nobody expects", "the spanish inquisition" );

// Testcode 
assertEquals( "the spanish inquisition", mockFoo.doSomething( "nobodyExpects" ) );

// Verify
mockFoo.verify();

Enhanced Features

By using MockObjects in Tests and with MockObjects being easily generated, it's possible to write tests that make it very hard to refactor any written code - because MockObjects may require a certain sequence of specified method calls.
There are several methods to avoid this - we recommend using all of them :-)

  • Use MockObjects with caution
  • Use Dummycalls (MockCreator-feature) where possible
  • Use Blocks containing code in arbitrary order (MockCreator feature).
  • ... there's probably more beyond the scope of this document ...

Use MockObjects with caution

Probably everybody must have seen the difficulties of refactoring Mock-tested code in his own project to be really aware of this problem.... ;-)

Use Dummycalls

With MockCreator-generated classes you can parameterize some method calls as "not relevant for test success" - among others, getters are good candidates for this. This causes the actual call of these methods during testing to be ignored by the mockobject.

// setup for MockObject
MockCustomer mockCustomer = new MockCustomer();
mockCustomer.setDummyGetName( "Joe Sixpack" );
mockCustomer.expectGetBalance( new Money( 10 ) );

// Create testee and test it 
ThisClassIsTested testee = new ThisClassIsTested( mockCustomer );
testee.thisMethodIsTested();

// Testcode in testee
public class ThisClassIsTested {
  private Customer _customer;
  public ThisClassIsTested( Customer customer ) { _customer = customer; }
  public void thisMethodIsTested() {
    doSomething( _customer.getName() );
    doSomethingElse( _customer.getName() );
    Money balance = _customer.getBalance();
    System.out.println( "Balance for Customer " + _customer.getName()
       + ": " + balance + " Euro" );
  }
  [...]
}

// Verify within TestCase
mockCustomer.verify();

Use Blocks containing code in arbitrary order

Usually MockCreator-generated Objects care for the order of function calls. Because this sometimes takes away flexibility from the implementation under test, it is possible to specify blocks of method calls may appear in any order.

// setup für das MockObject
MockFoo mockFoo = new MockFoo();
mockFoo.expectDoSomething( "nobody expects", "the spanish inquisition" );
mockFoo.startBlock();
mockFoo.expectSquareRoot( 4, 2 );
mockFoo.expectSquareRoot( 9, 3 );
mockFoo.expectSquareRoot( 16, 4 );
mockFoo.endBlock();
// Testcode aus der Testklasse 
// Testcode aus der zu testenden Klasse
public class ThisClassIsTested {
  private Foo _foo;
  public ThisClassIsTested( Foo foo ) { _foo = foo; };
  public void thisMethodIsTested() {
		_foo.doSomething( "nobody expects" ) );
		System.out.println( "sqrt(16) is " + _foo.squareRoot( 16 ) );
		System.out.println( "sqrt(4) is "  + _foo.squareRoot( 4 ) );
		System.out.println( "sqrt(9) is "  + _foo.squareRoot( 9 ) );
  }
  [...]
}
// Verifizierung
mockFoo.verify();

Generated code - short overview

Every call to an expectXY-Method saves an Object-Array with methodname and parameters in an ExpectationList as well as the return value in a list of return values.

Every actual method call compares the called method and parameters to the ones parameterized in the expectXY-method.

To test simulated error conditions two expectXY-methods are generated:

public void expectMethodName
               ( [all parameters]
                 [, return value if not void]
               );
public void expectMethodName
               ( [all parameters]
                 [, Throwable to be thrown
                         on method call]
               );

Using the second version you may simulate error conditions that the testee should handle (like lost database connections etc.). If the Throwable you pass into this method doesn't match the method signature, a ClassCastException will be raised during the test. To be sure pass only RuntimeExceptions or declare the exception within the interface.

If the number (and order) of certain method calls is irrelevant for test success, use setDummyXY>-methods.

public void setDummyMethodCall( [return value if not void] );
public void setDummyMethodCall( [Throwable, to be thrown on method call] );

To specify blocks of method calls with irrelevant order, use startBlock and endBlock.

public void startBlock();
public void endBlock();

Features

  • New in Version 0.2: Supporting Visual Age 4, Eclipse 2, Commandline
  • New in Version 0.2: Blocks of method calls with arbitrary order
  • Generates mockobjects based on Interfaces
  • Takes interface hierarchies into account
  • Generates the methods implementing the interface and two expect methods per interface method
  • Mockobjects are verifyable to easily check the correctness of called methods
  • If the source of the interface is present in the workspace, parameter names are used for the method generation
  • If only the byte code ist present in the workspace, the mockobjects are created via reflection
  • Free + open sourced

Planned features for upcomming releases

  • More & better docs
  • Parameterize method generation to be able to generate method names following com.mockobjects.* standard naming

Please let us know what features you prefer or if you have other enhancements ideas

Support, Contact

MockCreator is free software, there's no warranty for the function of the software. Of course we like to help if problems or questions arise.

Please use the mailinglist at Mailinglist at sourceforge for feedback, bugreports and general discussion.

Known Bugs and ToDos

  • There are problems with linux: the jar name is wrong (case sensitive file system) but there are some more problems that we are currently looking for. It seems only the windows version is working currently. If you can provide help, please do.
  • No generation of MockObjects for Interfaces without package (aka "default package")
  • generated classes follow (for historical reasons) our own naming scheme, not the one established with com.mockobjects.* (expect... instead of setExpected... etc.)
  • see the platform specific pages for platform specific issues.

License

The MockCreator is licensed under the
GNU General Public License (GPL), the imported classes (package de.abstrakt.mock) are licensed under the GNU Lesser General Public License (LGPL). This means, the generated classes are useful in closed source projects as well.
This software uses other software (com.mockobjects.*) that has to be obtained separately and is currently licensed under the apache license.

Copyright (C) 2001 abstrakt gmbh

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License and GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.