org.wounittest
Class MockEditingContext

java.lang.Object
  extended by com.webobjects.eocontrol.EOObjectStore
      extended by com.webobjects.eocontrol.EOEditingContext
          extended by org.wounittest.MockEditingContext
All Implemented Interfaces:
EOKeyValueArchiving, EOObserving, NSDisposable, NSLocking, Serializable

public class MockEditingContext
extends EOEditingContext

MockEditingContext is a subclass of EOEditingContext that can be used for fast in-memory testing of business objects.

Unit tests for logic which use fetch specifications or save to an editing context can be relative slow because full roundtrips to a database are being performed. Testing the same logic with a MockEditingContext ensures that nothing is being saved to or read from a database resulting in shorter execution time of the unit test. Also, you don't risk invalidating the persistent data with broken test cases.

Assuming there is an EOCustomObject called Person with the attributes name, age, nationality and partner. nationality is of entity Country for which there is a constant list of objects in the database. We want to write a test for the static Person method createFromDescription(String, EOEditingContext).

 import org.junit.*;
 import static org.junit.Assert.*;
 import org.wounittest.*;
 import static org.wounittest.WOAssert.*;


 public class PersonTest extends EOFTest {
     Person jane;

     @Before
     public void setUp() throws Exception {
         super.setUp();
         mockEditingContext().setEntityNamesToGetFromDatabase(new NSArray("Country"));
         jane = (Person)mockEditingContext().createSavedObject("Person");
         jane.setName("Jane Doe");
         jane.setNationalityRelationship(Country.withName("Canada", mockEditingContext()));
     }

     @Test
     public void creationFromDescriptionWithExistingPartner() {
         Person newPerson = Person.createFromDescription("John Doe, 34, Canada, Jane Doe",
                                                         mockEditingContext());
         assertEquals("John Doe", newPerson.name());
         assertEquals(34, newPerson.age());
         assertSame(Country.withName("Canada", mockEditingContext()), newPerson.nationality());
         assertSame(jane, newPerson.partner());
     }

     @Test
     public void creationFromDescriptionWithUnknownPartner() {
         Person newPerson = Person.createFromDescription("Bla Fasel, 12, Germany, Jeniffer Doe",
                                                         mockEditingContext());
         assertEquals("Blah Fasel", newPerson.name());
         assertEquals(12, newPerson.age());
         assertSame(Country.withName("Germany", mockEditingContext()), newPerson.nationality());
         assertNull(newPerson.partner());
     }

     @Test(expected = UnknownCountryException.class)
     public void creationFromDescriptionWithUnknownCountry() {
         Person.createFromDescription("Bla Fasel, 12, Wawaland, Jane Doe",
                                      mockEditingContext());
     }

 }
 

Additional information can be found in WOUTMockEditingContextTest.java.

See Also:
Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from class com.webobjects.eocontrol.EOEditingContext
EOEditingContext._EventLoggingEnabler, EOEditingContext.Delegate, EOEditingContext.EditingContextEvent, EOEditingContext.Editor, EOEditingContext.MessageHandler
 
Nested classes/interfaces inherited from interface com.webobjects.eocontrol.EOKeyValueArchiving
EOKeyValueArchiving._NullValueSupport, EOKeyValueArchiving._NumberSupport, EOKeyValueArchiving._TimestampSupport, EOKeyValueArchiving.Awaking, EOKeyValueArchiving.FinishInitialization, EOKeyValueArchiving.Support
 
Field Summary
protected  NSArray entityNamesToGetFromDatabase
           
protected static int fakePrimaryKeyCounter
           
protected  NSMutableArray ignoredObjects
           
 
Fields inherited from class com.webobjects.eocontrol.EOEditingContext
_CLASS, _EditingContextDidChangeSharedEditingContextNotification, _EditingContextEditorHasChangesNotification, _IsEventLoggingEnabled, EditingContextDidSaveChangesNotification, EditingContextFlushChangesRunLoopOrdering, ObjectsChangedInEditingContextNotification
 
Fields inherited from class com.webobjects.eocontrol.EOObjectStore
_doAssertLock, _doAssertLockInitialized, _wasDisposed, DeletedKey, InsertedKey, InvalidatedAllObjectsInStoreNotification, InvalidatedKey, ObjectsChangedInStoreNotification, UpdatedKey
 
Fields inherited from interface com.webobjects.foundation.NSLocking
OneCentury, OneDay, OneHour, OneMinute, OneSecond, OneWeek, OneYear
 
Constructor Summary
MockEditingContext()
          Constructs a MockEditingContext.
 
Method Summary
protected  EOGlobalID assignFakeGlobalIDToObject(EOCustomObject anObject)
          Internal helper method for insertSavedObject.
 EOCustomObject createSavedObject(String anEntityName)
          Convenience cover method for insertSavedObject.
 void dispose()
          Extends the implementation inherited from EOEditingContext to delete ignoredObjects.
 void insertSavedObject(EOCustomObject anObject)
          Inserts a Custom Object into the receiver and makes it look as if it was fetched from the database.
 NSArray objectsWithFetchSpecification(EOFetchSpecification aFetchSpecification, EOEditingContext anEditingContext)
          Overrides the implementation inherited from EOEditingContext to fetch objects from the array of registeredObjects of the receiver instead of going to the database.
 void objectWillChange(Object anObject)
          Overrides the implementation inherited from EOEditingContext to ignore objects registered with insertSavedObject.
 EOObjectStore rootObjectStore()
          Overwritten to return the defaultParentObjectStore.
 void setEntityNamesToGetFromDatabase(NSArray theEntityNamesToGetFromDatabase)
          Defines which entities should be fetched from the rootObjectStore.
 
Methods inherited from class com.webobjects.eocontrol.EOEditingContext
_clearChangedThisTransaction, _clearOriginalSnapshotAndInitializeRec, _clearOriginalSnapshotForObject, _defaultEditingContextNowInitialized, _defaultSharedEditingContextWasInitialized, _editorHasChanges, _EOAssertSafeMultiThreadedAccess, _EOAssertSafeMultiThreadedAccess, _EOAssertSafeMultiThreadedReadAccess, _globalIDChanged, _globalIDsForObjects, _initWithParentObjectStore, _insertObjectWithGlobalID, _invalidatedAllObjectsInStore, _invalidateObjectsDuringSave, _noop, _objectBasedChangeInfoForGIDInfo, _objectsChangedInStore, _objectsInitializedInSharedContext, _processEndOfEventNotification, _processGlobalIDChanges, _processInitializedObjectsInSharedContext, _processNotificationQueue, _processObjectStoreChanges, _processRecentChanges, _resetAllChanges, _resetAllChanges, _retainCountForObjectWithGlobalID, _undoDelete, _undoManagerCheckpoint, _undoUpdate, addEditor, arrayFaultWithSourceGlobalID, committedSnapshotForObject, currentEventSnapshotForObject, decodeWithKeyValueUnarchiver, defaultFetchTimestampLag, defaultParentObjectStore, delegate, deletedObjects, deleteObject, editingContextDidForgetObjectWithGlobalID, editors, editorsHaveChanges, encodeObjectWithCoder, encodeWithKeyValueArchiver, faultForGlobalID, faultForRawRow, faultForRawRow, fetchTimestamp, finalize, forgetObject, globalIDForObject, hasChanges, initializeObject, initObjectWithCoder, insertedObjects, insertObject, insertObjectWithGlobalID, instancesRetainRegisteredObjects, invalidateAllObjects, invalidateObjectsWithGlobalIDs, invalidatesObjectsWhenFinalized, invokeRemoteMethod, isObjectLockedWithGlobalID, lock, lockObject, lockObjectStore, lockObjectWithGlobalID, locksObjectsBeforeFirstModification, messageHandler, objectForGlobalID, objectsForSourceGlobalID, objectsWithFetchSpecification, parentObjectStore, processRecentChanges, propagatesDeletesAtEndOfEvent, readResolve, recordObject, redo, refaultAllObjects, refaultObject, refaultObject, refaultObjects, refetch, refreshAllObjects, refreshObject, registeredObjects, removeEditor, reset, retainsRegisteredObjects, revert, saveChanges, saveChanges, saveChangesInEditingContext, setDefaultFetchTimestampLag, setDefaultParentObjectStore, setDelegate, setFetchTimestamp, setInstancesRetainRegisteredObjects, setInvalidatesObjectsWhenFinalized, setLocksObjectsBeforeFirstModification, setMessageHandler, setPropagatesDeletesAtEndOfEvent, setRetainsRegisteredObjects, setSharedEditingContext, setStopsValidationAfterFirstError, setSubstitutionEditingContext, setUndoManager, setUsesContextRelativeEncoding, sharedEditingContext, stopsValidationAfterFirstError, substitutionEditingContext, tryLock, tryToSaveChanges, undo, undoManager, unlock, unlockObjectStore, updatedObjects, usesContextRelativeEncoding
 
Methods inherited from class com.webobjects.eocontrol.EOObjectStore
_checkAssertLock, _resetAssertLock, _suppressAssertLock
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

fakePrimaryKeyCounter

protected static int fakePrimaryKeyCounter

ignoredObjects

protected NSMutableArray ignoredObjects

entityNamesToGetFromDatabase

protected NSArray entityNamesToGetFromDatabase
Constructor Detail

MockEditingContext

public MockEditingContext()
Constructs a MockEditingContext. Using a MockObjectStore as parent object store.

Method Detail

setEntityNamesToGetFromDatabase

public void setEntityNamesToGetFromDatabase(NSArray theEntityNamesToGetFromDatabase)
Defines which entities should be fetched from the rootObjectStore. This can be useful for tests which depend on some data being present in the database.

Parameters:
theEntityNamesToGetFromDatabase - array of entity names which should be fetched from the database

rootObjectStore

public EOObjectStore rootObjectStore()
Overwritten to return the defaultParentObjectStore.

Overrides:
rootObjectStore in class EOEditingContext
See Also:
EOEditingContext.defaultParentObjectStore()

objectsWithFetchSpecification

public NSArray objectsWithFetchSpecification(EOFetchSpecification aFetchSpecification,
                                             EOEditingContext anEditingContext)
Overrides the implementation inherited from EOEditingContext to fetch objects from the array of registeredObjects of the receiver instead of going to the database. Only entities defined with setEntityNamesToGetFromDatabase are still being fetched from the database using the rootObjectStore. Throws UnsupportedOperationException if aFetchSpecification is configured to return raw rows. Hints are ignored.

Overrides:
objectsWithFetchSpecification in class EOEditingContext
Parameters:
aFetchSpecification - the criteria specified for fetch
anEditingContext - the destination EOEditingContext, needs to be the same as the receiver

createSavedObject

public EOCustomObject createSavedObject(String anEntityName)
Convenience cover method for insertSavedObject. Creates a new Custom Object for the specified entity, inserts it into the receiver using insertSavedObject, and returns the new object.

Parameters:
anEntityName - the name of entity

insertSavedObject

public void insertSavedObject(EOCustomObject anObject)
Inserts a Custom Object into the receiver and makes it look as if it was fetched from the database. The object will get a non-temporary global id. The receiver will not observe the object as defined in EOObserving, which means after changing the object, the receiver will not validate or save it. Doesn't work with EOCustomObject subclasses that have a compound primary key. Note that awakeFromInsertion() will be called on the object because that method often contains useful initialization, and awakeFromFetch() will NOT be called because it might depend on data that we don't care to set up.

Parameters:
anObject - the Custom Object

assignFakeGlobalIDToObject

protected EOGlobalID assignFakeGlobalIDToObject(EOCustomObject anObject)
Internal helper method for insertSavedObject.


objectWillChange

public void objectWillChange(Object anObject)
Overrides the implementation inherited from EOEditingContext to ignore objects registered with insertSavedObject.

Specified by:
objectWillChange in interface EOObserving
Overrides:
objectWillChange in class EOEditingContext
Parameters:
anObject - the object whose state is to be recorded

dispose

public void dispose()
Extends the implementation inherited from EOEditingContext to delete ignoredObjects.

Specified by:
dispose in interface NSDisposable
Overrides:
dispose in class EOEditingContext