Envelope/Quill MockObjects

- Last edited February 18, 2003
The original version of the paper that documents MockObjects can be found at: www.mockobjects.com/endotesting.html

MockMaker creates MockObjects from Java Interfaces.

MockObjects infrastructure code can be found at www.mockobjects.com

MockObjects libraries for other languages: MockObjectsPython, MockObjectsRuby

For RonJefferies? take on MockObjects see: RonJefferiesOnMockObjects

A thought. Extensive use of MockObjects allows the testing of the system to test PreConditions? as well as PostConditions? and Invariants of classes. PreConditions? are an area that is not well served by 'standard' Unit Tests. --TomAyerst

That sounds weird to me. Surely you test in the presence of PreConditions?, rather than actually testing them? That said, MockObjects make them easier to set up and more explicit. --SteveF

Hmm, not sure now. In Design ByContract? there are postconditions and invariants (that it is the responsibility of the called class to ensure) and preconditions (that it is the responsibility of the calling class to ensure).

The thought was that, without putting precondition assertions in the system code, you can test that a calling object ensures that the called object is in the correct by putting in a mock called object in place with the requiste expectations. Standard tests only check that the tested object performs its part of the contract properly and ends up in a valid state. Are we agreeing or have I missed something? --TomA


I've moved a discussion here from Egroups on UnitTestingAroundThirdParties --SteveF


There is a new article on EarthWeb? about Cactus discussing (a little) Mock Objects and In-Container testing (softwaredev.earthweb.com/java/article/0,,12082_793701,00.html). I'm sorry if everything written is not accurate or not complete but bear in mind that it was written by a journalist ... ! :) (nah, just kidding)

--VincentMassol


Something I miss in most MockObjects discussions: MockObjects are easy to use if your class only uses objects passed as parameters. But what about objects that are owned/created inside the class under test? Unless the objects are created using some kind of factory method that you can override, it's near impossible to swap in the MockObject. That's the main reason stubs normally are swapped in at compile time.

At Wordtracker we occasionally use an automated system for overriding the factories which for want of a better name we have called PartialMocks. Sometimes I like to rfactor the code a little rather than add the extra logic from optional parameters (below). -- MarcuS

I've found that the best approach is to use factories which you pass in to the object which needs to create other objects. This make it easy to swap in other implementations mock or other wise and it allows you to test that the internal objects are being created. i.e. your passing in the right arguments, creating the right number of objects. I've also found that is can help with memory management e.g.

public void createMyObject(...){

    try{
        new MemoryHungryObject?(...);
    }catch(OutOfMemoryError? e){ // Usually it's a really bad idea to catch this
        // eek. not memory. ask some memory manager object to try
        // releasing some objects (probably in Hash Maps)
        cacheManager.release();
        new MemoryHungryObject?(...);
    }
}

The MockObject project is starting to produce factories for standard Java objects like java.io.File so that mock implementations can be used. It doe's mean we have to create proper interfaces for object to though. Hence the creation of alt.java.io.File, alt.java.io.FileImpl with allow us to use com.mockobjects.io.File woo hoo

-- JeffMartin

I've used MockObjects a lot in C++ (and like them) and it is tempting to include "test-only" methods in your class that allow you to swap in the MockObject. But that's not a nice solution.

Do you encourage a programming style where objects have no members but only use parameters? Looks like a very restrictive version of the DemeterLaw?...

Any comments? --ErnestoGuisado

Quite often we might add, say, an extra constructor that accepts one of the internal objects. The default constructor will create a real instance. In practice, this doesn't hurt very much and sometimes proves really useful. We also tend to write more factory objects than is common but, again, that often proves useful after the fact. I can imagine this being especially true in C++. We also keep our classes small, so we tend to avoid too many instance variables. --SteveF

In some languages, you can pass mock objects as arguments to the constructor that have default values which create the real objects. So the common case initialises the object correctly, but passing in constructor arguments overrides that initialisation and allows mock objects to be used instead. E.g. in Python:

  class Reactor:
      def __init__( self, event_queue = System_Event_Queue() ):
          self.event_queue = event_queue

def run( self ): while 1: event = event_queue.wait_for_event() if event.type == EVENT_QUIT: return else: dispatch_event( event )
# Create a reactor that dispatches events from the system event queue reactor = Reactor()
# Create a reactor that dispatches mocked events mock_queue = Mock_Event_Queue() reactor = Reactor( mock_queue )
---

Saw a nice article on using mock objects with Aspect-J on IBM developer works (www-106.ibm.com/developerworks/library/j-aspectj2/index.html) -- VanEmmenis (28-Aug-02)

---

Here's a plug for NMock (nmock.truemesh.com/) - a very simple to use dynamic mock object library.


- Last edited February 18, 2003

https://casino-brain.com/