Giter VIP home page Giter VIP logo

wounit's Introduction

๐Ÿš€ About Me

I'm a seasoned full-stack developer with over 20 years of experience designing JVM-based web applications. I've worked on a wide range of projects, from mission-critical software for the pharmaceutical industry to e-commerce payments that are used by thousands of users daily. I am passionate in creating software that is simple to use and easy to read and maintain. I'm also a big advocate of test-driven development. In addition to my technical skills, I have experience leading and managing small teams of developers, fostering collaboration, and achieving project goals efficiently. Being a perfectionist, I am constantly looking for new methods to improve my abilities and knowledge. When I'm not working, I enjoy spending time with friends and family, traveling, and reading books.

๐Ÿ‘ฏ Skills

My expertise spans a diverse range of programming languages, including:

  • Java
  • Clojure / ClojureScript
  • JavaScript
  • Kotlin
  • Scala
  • C

๐Ÿ”ง Core Competencies

Over the years, I've cultivated a comprehensive skillset, encompassing:

  • Software Testing and Test-Driven Development
  • Object-Oriented Programming
  • Functional Programming
  • Software Architecture and Modularization
  • Service-Oriented Architectures
  • Application Profiling and Optimization
  • User Experience

๐Ÿ› ๏ธ Projects

I've led the development of several open-source projects, including:

I'm also a contributor on the following open-source projects:

๐Ÿ“ซ Connect With Me

Feel free to reach out to me at [email protected] to discuss potential collaborations. I'm also on X (formely Twitter) and LinkedIn.

wounit's People

Contributors

actions-user avatar hprange avatar jcranky avatar kierankelleher avatar rdskill avatar zigdra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

wounit's Issues

Add support for MockEditingContext approach

WOUnitTest is an excellent library to write unit tests for WebObjects projects. But it is outdated and doesn't support Wonder.

We must provide a similar but updated solution using the MockEditingContext approach.

Add parameter to allow creation of dummy objects for abstract types

Occasionally, creating a dummy object for a abstract type is desirable. We can add a of parameter to the @Dummy annotation describing the concrete type that should be created like this:

@Dummy(of=Concrete.class)
Abstract dummyAbstract;

We must also support the creation of an array of dummies:

@Dummy(of=Concrete.class, size=2)
NSArray<Abstract> dummyAbstract;

Error spying EO using recent Mockito version

Test is throwing the following exception when running against a recent version of Mockito:

org.mockito.exceptions.base.MockitoException: Unable to initialize @Spy annotated field 'boletoReference'.
Unable to create mock instance of type 'BoletoReference'
	at org.mockito.internal.runners.DefaultInternalRunner$1.withBefores(DefaultInternalRunner.java:38)
	at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:276)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:78)
	at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:84)
	at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
	at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.mockito.exceptions.base.MockitoException: Unable to create mock instance of type 'BoletoReference'
	... 20 more
Caused by: org.mockito.internal.creation.instance.InstantiationException: 
Unable to create instance of 'BoletoReference$MockitoMock$1334867616'.
Please ensure the target class has a 0-arg constructor and executes cleanly.
	... 20 more
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
	at org.mockito.internal.creation.instance.ConstructorInstantiator.invokeConstructor(ConstructorInstantiator.java:64)
	at org.mockito.internal.creation.instance.ConstructorInstantiator.withParams(ConstructorInstantiator.java:48)
	at org.mockito.internal.creation.instance.ConstructorInstantiator.newInstance(ConstructorInstantiator.java:34)
	at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:47)
	at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:25)
	at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
	at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
	at org.mockito.Mockito.mock(Mockito.java:1798)
	at org.mockito.internal.configuration.SpyAnnotationEngine.spyNewInstance(SpyAnnotationEngine.java:114)
	at org.mockito.internal.configuration.SpyAnnotationEngine.process(SpyAnnotationEngine.java:65)
	at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:59)
	at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:41)
	at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:69)
	... 20 more
Caused by: java.lang.IllegalStateException: Unabled to find an EOClassDescription for objects of class br.com.doit.money.gateway.model.BoletoReference$MockitoMock$1334867616
	at com.webobjects.eocontrol.EOGenericRecord.__setClassDescription(EOGenericRecord.java:98)
	at com.webobjects.eocontrol.EOGenericRecord.<init>(EOGenericRecord.java:73)
	at er.extensions.eof.ERXGenericRecord.<init>(ERXGenericRecord.java:103)
	at br.com.doit.money.gateway.model.base._BoletoReference.<init>(_BoletoReference.java:14)
	at br.com.doit.money.gateway.model.BoletoReference.<init>(BoletoReference.java:16)
	at br.com.doit.money.gateway.model.BoletoReference$MockitoMock$1334867616.<init>(Unknown Source)
	... 37 more

That is the Mockito dependency declaration in the pom.xml.

<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-core</artifactId>
   <version>2.10.0</version>
   <scope>test</scope>
</dependency>

An exception in the cleanup code hide the original exception in failing test cases

Here is an example of exception occurred after the test case execution:

java.lang.NullPointerException
at com.webobjects.eocontrol.EOEditingContext._forgetObject(EOEditingContext.java:1556)
at com.webobjects.eocontrol.EOEditingContext._dispose(EOEditingContext.java:1183)
at com.webobjects.eocontrol.EOEditingContext.dispose(EOEditingContext.java:1111)
at er.extensions.eof.ERXEC.dispose(ERXEC.java:762)
at com.wounit.rules.AbstractEditingContextRule.after(AbstractEditingContextRule.java:115)
at com.wounit.rules.MockEditingContext.after(MockEditingContext.java:136)
at com.wounit.rules.AbstractEditingContextRule$1.evaluate(AbstractEditingContextRule.java:143)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
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)

ERXLocalizer is not initialized properly

The ERXLocalizer class is unable to find the *.strings. It shouldn't load those files by default, but the WOUnit could provide a mechanism to initialize the localizer properly if required.

ClassCastException when testing partial entities

(Henrique, this is just a placeholder issue for completeness. I know you're all over this, and the fix in your 1.3-SNAPSHOT-partials-fix worked.)

I want to write some WOUnit tests for a class that extends ERXPartialGenericRecordโ€”that is, a "base entity" in the partial entities terminology. I have a simple User class in a model called Ident:

public class UserTest {
    @Rule
    public MockEditingContext ec = new MockEditingContext("Ident");

    @Test
    public void createUser() {
        User u = User.createUser(ec, "password", "username");
        confirm(u, canBeSaved());
        return;
    }
}

This test fails with the following (abridged) stack trace:

java.lang.ClassCastException: com.webobjects.eoaccess.EOEntityClassDescription cannot be cast to er.extensions.eof.ERXEntityClassDescription
    at er.extensions.partials.ERXPartialGenericRecord._partialsDictionary(ERXPartialGenericRecord.java:40)
    at er.extensions.partials.ERXPartialGenericRecord._partials(ERXPartialGenericRecord.java:64)
    at er.extensions.partials.ERXPartialGenericRecord.awakeFromInsertion(ERXPartialGenericRecord.java:179)
    at com.webobjects.eocontrol.EOEditingContext.insertObjectWithGlobalID(EOEditingContext.java:2871)
    at er.extensions.eof.ERXEC.insertObjectWithGlobalID(ERXEC.java:976)
    at com.webobjects.eocontrol.EOEditingContext.insertObject(EOEditingContext.java:2889)
    at er.extensions.eof.ERXEC.insertObject(ERXEC.java:987)
    at com.webobjects.eoaccess.EOUtilities.createAndInsertInstance(EOUtilities.java:862)
    at net.logicsquad.access.model._User.createUser(_User.java:180)
    at net.logicsquad.access.tests.UserTest.createUser(UserTest.java:20)

Implement TestRule to conform JUnit 4.9

Copied from JUnit 4.9 release notes:

In JUnit 4.9, fields that can be annotated with either @Rule or @ClassRule
should be of type TestRule. The old MethodRule type, which only made sense
for method-level rules, will still work, but is deprecated.

Most built-in Rules have been moved to the new type already, in a way that
should be transparent to most users. TestWatchman has been deprecated,
and replaced by TestWatcher, which has the same functionality, but implements
the new type.

NSArray key operators defined by Wonder are not initialized by default

The lack of initialization causes the following exception:

java.lang.IllegalArgumentException: No key operator available to compute aggregate @flatten
    at com.webobjects.foundation.NSArray._valueForKeyPathWithOperator(NSArray.java:742)
    at com.webobjects.foundation.NSArray.valueForKeyPath(NSArray.java:774)
    at com.webobjects.foundation.NSKeyValueCodingAdditions$Utility.valueForKeyPath(NSKeyValueCodingAdditions.java:149)
    at com.webobjects.foundation.NSKeyValueCodingAdditions$DefaultImplementation.valueForKeyPath(NSKeyValueCodingAdditions.java:217)
    at com.webobjects.foundation.NSArray.valueForKeyPath(NSArray.java:776)
    at com.webobjects.foundation.NSKeyValueCodingAdditions$Utility.valueForKeyPath(NSKeyValueCodingAdditions.java:149)
    at er.extensions.eof.ERXKey.rawValueInObject(ERXKey.java:2099)
    at er.extensions.eof.ERXKey.valueInObject(ERXKey.java:2088)
    at br.com.doit.model.project.Supplier.chargeAvailableReserve(Supplier.java:33)
    at br.com.doit.model.project.TestSupplier.includePastNotReconciledAccountingEntryWhenCreatingProjectBill(TestSupplier.java:83)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at com.wounit.rules.AbstractEditingContextRule$1.evaluate(AbstractEditingContextRule.java:157)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    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)

Testing validateForInsert()

I have an EO that splits some save-time validation logic between validateForSave() and validateForInsert(), with the latter method being called just for new objects. I can't test this using something like confirm(eo, canBeSaved()), because CanBeSavedMatcher.matchesWithPossibleException() only calls validateForSave(). Obviously I could test it directly by calling validateForInsert(), but could we get WOUnit to do this for us? I see a couple of possibilities:

  • A new CanBeInsertedMatcher.
  • Adding a call to validateForInsert() to CanBeSavedMatcher.matchesWithPossibleException() on the condition that isNewObject() was true.

Would either of these approaches be suitable, and which would be preferred? I am happy to do the work and open a PR, though it's not clear whether WOUnit development is ongoingโ€”let me know!

Support spied objects with Mockito

Mockito is a really nice and useful Mock framework and it has a powerful implementation of test spies. Spied objects can be partially stubbed, without changing the overall behavior of the object. Spying EOs requires a couple of boilerplate code and the WOUnit annotations cannot be used:

@test
public void testSomething() {
Foo foo = Mockito.spy(new Foo());
ec.insertSavedObject(foo);
}

We could offer a better option:

@SPY @dummy
private Foo foo;

I have to check if the @SPY annotation from Mockito will play nice in this scenario. Otherwise, the WOUnit can provide a different annotation (@spied maybe) to avoid naming clash.

IMPORTANT: Mockito must not be a requirement for people in order to make use of WOUnit.

WOUnit doesn't propagate delete when validating objects for deletion

The implementation of the CanBeDeletedMatcher can lead to code that will pass the tests but will fail in production.

WOUnit offers a matcher to verify if an object can or cannot be deleted. The implementation of this matcher is simple. It calls only the validateForDelete method on the object being verified. Considering how EOF works, this implementation is not enough. It doesn't guarantee, for instance, that the state of the object will be correct when firing the validation code while running tests.

In production, two actions execute before the validation and may change the state of an object. The ERXEC calls the ERXEnterpriseObject.mightDelete method when the object is deleted, and the original EOEditingContext propagates the deletion over related objects (applying the delete rules defined in the EOModel) when the editing context is saved. If a relationship has a delete rule of type Nullify or Cascade, it will no longer be in place when the validation is executed.

The following uses of the CanBeDeletedMatcher are affected by this issue:

confirm(eo, canBeDeleted());
confirm(eo, cannotBeDeleted());
confirm(eo, cannotBeDeletedBecause("reason"));

To fix this problem, the CanBeDeletedMatcher should call the ERXEnterpriseObject.mightDelete and the EOEnterpriseObject.propagateDeleteWithEditingContext methods before calling the validateForDelete method.

Configure Maven to produce the WOUnit main site

Now that I have developed a logo, it's time to configure Maven to produce the main website for this project. Some topics that should be covered in the site.

-User Guide
-Download
-Javadoc
-Source Code
-Coverage Report
-Link to GitHub

Add the Ant configuration to build the WOUnit project

Maven is really cool, but not everyone like it. Adding a build.xml script could be useful for a broader audience.

BTW, you can execute 'mvn ant:ant' to generate the corresponding build.xml based on the project's pom.xml.

Ongoing issue with EOModel.createPrototypeCache()

I'm opening a new ticket here to distinguish it from #35 which is probably the same issue, but it wouldn't seem to have anything to do with partial entities (at least directly).

As reported in #35, the fix to ERXModelGroup seemed to clear up the problem for me, until it didn't. I'm still seeing it intermittently, though only running in Eclipse. It seems to be solid on Jenkins, though maybe I haven't run it enough times to see it. Further, sometimes it will fail on one test in a class (usually the first) and then proceed to pass on all the others. Here's a stack trace from my RoleTest class, testing an entity called Role which is not a partial entity:

com.webobjects.foundation.NSForwardException [java.lang.reflect.InvocationTargetException] null:java.lang.reflect.InvocationTargetException
    at com.webobjects.foundation._NSUtilities._explainInstantiationException(_NSUtilities.java:626)
    at com.webobjects.foundation._NSUtilities.instantiateObjectWithConstructor(_NSUtilities.java:665)
    at com.webobjects.eoaccess.EOEntityClassDescription.createInstanceWithEditingContext(EOEntityClassDescription.java:242)
    at com.webobjects.eoaccess.EOUtilities.createAndInsertInstance(EOUtilities.java:861)
    at com.wounit.rules.AbstractEditingContextRule$UnderTestFacade.create(AbstractEditingContextRule.java:72)
    at com.wounit.rules.AnnotationProcessor.createEOForType(AnnotationProcessor.java:49)
    at com.wounit.rules.AnnotationProcessor.initializeObject(AnnotationProcessor.java:172)
    at com.wounit.rules.AnnotationProcessor.process(AnnotationProcessor.java:205)
    at com.wounit.rules.AbstractEditingContextRule.before(AbstractEditingContextRule.java:182)
    at com.wounit.rules.MockEditingContext.before(MockEditingContext.java:147)
    at com.wounit.rules.AbstractEditingContextRule$1.evaluate(AbstractEditingContextRule.java:162)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    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)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.webobjects.foundation._NSUtilities.instantiateObjectWithConstructor(_NSUtilities.java:659)
    ... 24 more
Caused by: java.lang.NullPointerException
    at com.webobjects.eoaccess.EOModel.createPrototypeCache(EOModel.java:631)
    at com.webobjects.eoaccess.EOModel.prototypeAttributeNamed(EOModel.java:699)
    at com.webobjects.eoaccess.ERXModel.prototypeAttributeNamed(ERXModel.java:290)
    at com.webobjects.eoaccess.EOAttribute.<init>(EOAttribute.java:998)
    at com.webobjects.eoaccess.EOEntity.attributes(EOEntity.java:816)
    at com.webobjects.eoaccess.EOEntity.attributeNamed(EOEntity.java:789)
    at com.webobjects.eoaccess.EOEntity.classProperties(EOEntity.java:1098)
    at com.webobjects.eoaccess.EOEntity._propertyDictionaryInitializer(EOEntity.java:3321)
    at com.webobjects.eoaccess.EOEntity._newDictionaryForProperties(EOEntity.java:3667)
    at com.webobjects.eoaccess.EOEntityClassDescription._newDictionaryForProperties(EOEntityClassDescription.java:88)
    at com.webobjects.eocontrol.EOGenericRecord.__setClassDescription(EOGenericRecord.java:111)
    at com.webobjects.eocontrol.EOGenericRecord.__setClassDescription(EOGenericRecord.java:100)
    at com.webobjects.eocontrol.EOGenericRecord.<init>(EOGenericRecord.java:73)
    at er.extensions.eof.ERXGenericRecord.<init>(ERXGenericRecord.java:103)
    at net.logicsquad.access.model._Role.<init>(_Role.java:15)
    at net.logicsquad.access.model.Role.<init>(Role.java:15)
    ... 29 more

I'm seeing the same telltale console output here when it fails:

- Entity classDescription is not ERXEntityClassDescription: Privilege
- Entity classDescription is not ERXEntityClassDescription: Role
- Entity classDescription is not ERXEntityClassDescription: RolePrivilege

and not when it passes.

Henrique, I am more than happy to send you a small test framework that exhibits the issue. Let me know if you want it.

Inherited fields are not correctly initialized

If you have a ParentTest:

public class ParentTest {
@rule
public MockEditingContext ec = new MockEditingContext("AnyModel");

@undertest
protected Foo foo;
}

And a ChildTest:

public class ChildTest extends ParentTest{
@test
public void anyTest() {
// Throws a NullPointerException
foo.bar();
}
}

Problem with Joda Time attributes in tests running in Eclipse

Summary: I've diagnosed the issue here, but I'll open (and close) this ticket so there's a reference to it.

I just started getting some failed unit tests when running in Eclipse. The stack trace points to difficulty loading Joda Time classes:

java.lang.IllegalStateException: adaptorValueType: unable to load class named 'LocalDateTime' for attribute date on entity SummaryLine
    at com.webobjects.eoaccess.EOAttribute.adaptorValueType(EOAttribute.java:2216)
    at com.webobjects.eoaccess.EOAttribute.adaptorValueClass(EOAttribute.java:2254)
    at com.webobjects.eoaccess.EOEntityClassDescription._enforcedKVCNumberClassForKey(EOEntityClassDescription.java:548)
    at er.extensions.eof.ERXEntityClassDescription._enforcedKVCNumberClassForKey(ERXEntityClassDescription.java:1280)
    at com.webobjects.eocontrol.EOGenericRecord._otherStorageBinding(EOGenericRecord.java:146)
    at er.extensions.eof.ERXGenericRecord._otherStorageBinding(ERXGenericRecord.java:234)
    at com.webobjects.foundation.NSKeyValueCoding$_ReflectionKeyBindingCreation._createKeyBindingForKey(NSKeyValueCoding.java:1719)
    at com.webobjects.foundation.NSKeyValueCoding$_ReflectionKeyBindingCreation._createKeyGetBindingForKey(NSKeyValueCoding.java:1742)
    at com.webobjects.eocontrol.EOKeyValueCoding$DefaultImplementation._createStoredKeyGetBindingForKey(EOKeyValueCoding.java:346)
    at com.webobjects.eocontrol.EOCustomObject._createStoredKeyGetBindingForKey(EOCustomObject.java:1740)
    at com.webobjects.eocontrol.EOGenericRecord._storedKeyGetBindingForKey(EOGenericRecord.java:203)
    at com.webobjects.eocontrol.EOCustomObject.storedValueForKey(EOCustomObject.java:1633)
    at com.webobjects.eocontrol.EOCustomObject.snapshot(EOCustomObject.java:515)
    at com.webobjects.eocontrol.EOEditingContext.objectWillChange(EOEditingContext.java:2813)
    at er.extensions.eof.ERXEC.objectWillChange(ERXEC.java:967)
    at com.wounit.rules.MockEditingContext.objectWillChange(MockEditingContext.java:295)
    at com.webobjects.eocontrol.EOObserverCenter.notifyObserversObjectWillChange(EOObserverCenter.java:399)
    at com.webobjects.eocontrol.EOCustomObject.willChange(EOCustomObject.java:333)
    at com.webobjects.eocontrol._EOMutableKnownKeyDictionary$Initializer$_GenericRecordBinding.setValueInObject(_EOMutableKnownKeyDictionary.java:579)
    at com.webobjects.eocontrol.EOCustomObject.takeStoredValueForKey(EOCustomObject.java:1663)
    at er.extensions.eof.ERXGenericRecord.takeStoredValueForKey(ERXGenericRecord.java:1261)
    at net.logicsquad.hydromaster.model.core._SummaryLine.setOrder(_SummaryLine.java:163)
    at net.logicsquad.hydromaster.model.core.SummaryLine.createSummaryLine(SummaryLine.java:212)
    at net.logicsquad.hydromaster.model.core.SummaryFile.createSummaryFile(SummaryFile.java:98)
    at net.logicsquad.hydromaster.test.model.core.SummaryFileTest.allTestFilesShouldBeParseable(SummaryFileTest.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at com.wounit.rules.AbstractEditingContextRule$1.evaluate(AbstractEditingContextRule.java:165)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    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)

Needless to say, I have ERAttributeExtension.framework on the classpath, and there are no issues with Joda attributes in the running application. Further, the tests all pass post-build on Jenkins.

The issue turns out to be due to having ERJars.framework (and ERExtensions.framework) open as projects in the workspace when running the tests. Close those projects, and the tests all pass.

Is this a classpath ordering thing? Is Eclipse setting up a different order than what I get when I use the wopath Ant element? And could that be affecting the tests?

Anyway, this is solved, and just preserved here for future reference. This is depressingly brittle.

NPE from TemporaryEditingContext.fixJavaMemoryDictionary

I have what I think is a very basic unit test using a TemporaryEditingContext. I create the TemporaryEditingContext using an @Rule annotation, load it up with a few EOs, saveChanges(), and then run the code under test using those EOs. This works fine in Eclipse, but I can't get it to run outside Eclipse using Hudson and Ant. Specifically, I get a NullPointerException during creation of the TemporaryEditingContext:

java.lang.NullPointerException
    [junit]     at com.wounit.rules.TemporaryEditingContext.fixJavaMemoryDictionary(TemporaryEditingContext.java:147)
    [junit]     at com.wounit.rules.TemporaryEditingContext.<init>(TemporaryEditingContext.java:80)
    [junit]     at net.logicsquad.webobjects.core.test.LSWOCSVUtilsTest.<init>(Unknown Source)
    [junit]     at java.lang.reflect.Constructor.newInstance(Constructor.java:513)

The issue is in this method:

private void fixJavaMemoryDictionary() {
    NSBundle bundle = NSBundle.bundleForName("JavaMemoryAdaptor");

    bundle._infoDictionary().takeValueForKey(ERMemoryAdaptor.class.getName(), "EOAdaptorClassName");
}

I actually had this error come up initially in Eclipse, and it was because I didn't have JavaMemoryAdaptor.framework on the build path. Outside of Eclipse, running ant -v shows that it is on the classpath for this test, though.

Any thoughts?

Add support for fetch specs defined in the EOModel

In the EOModel I have a fetch spec defined with the qualifier $patient of type Patient. This auto-generates a method which does:

public static NSArray<net.starhealthcare.sffoundation.model.SFIncident> fetchIncidentsWithDiagnosesForPatient(EOEditingContext editingContext, NSDictionary<String, Object> bindings) {
  EOFetchSpecification fetchSpec = EOFetchSpecification.fetchSpecificationNamed("fetchSpecName", "Incident");
  fetchSpec = fetchSpec.fetchSpecificationWithQualifierBindings(bindings);
  return editingContext.objectsWithFetchSpecification(fetchSpec);
}

I then call it like this:

fetchIncidentsWithDiagnosesForPatient(this.editingContext(), patient);

This does not work with WOUnit, the following exception gets thrown:

com.webobjects.eocontrol.EOQualifier$QualifierVariableSubstitutionException: Error in variable substitution: value for variable $patient not found
at com.webobjects.eocontrol.EOKeyValueQualifier.qualifierWithBindings(EOKeyValueQualifier.java:270)
at com.webobjects.eocontrol.EOQualifier._andOrQualifierWithBindingsAndOptions(EOQualifier.java:719)
at com.webobjects.eocontrol.EOAndQualifier.qualifierWithBindings(EOAndQualifier.java:146)
at com.webobjects.eocontrol.EOFetchSpecification.fetchSpecificationWithQualifierBindings(EOFetchSpecification.java:182)

Improve error message when model cannot be loaded

When a model cannot be loaded, the editing context rule notify the user, but gives no clue about the problem. The message could include a list of available models and, if possible, suggest a fix for the name in case of a typo.

Problem with @Spy annotations

I get the error below when trying to run the following test using Maven. I have used the mockito @SPY annotation many times before and never got this issue. In the past however, my unit tests would always reside within frameworks.. Somehow this type of test doesn't run if the model is part of an external framework used is by the application.

@RunWith(MockitoJUnitRunner.class)
public class BasicTest {

    @Rule
    public MockEditingContext   _editingContext = new MockEditingContext("ModelName");

    @Dummy
        @Spy
    Membre                      membre;

    @Test
    public void test() {
        assertTrue(true);
    }

}

test(com.acaiq.certification.controleur.ControleurFusionTest) Time elapsed: 1.121 sec <<< ERROR!
com.webobjects.foundation.NSKeyValueCoding$UnknownKeyException: <com.acaiq.fondation.acaiqCore.Membre$$EnhancerByMockitoWithCGLIB$$75eb343 0x5c7c22ce> takeValueForKey(): attempt to assign value to unknown key: 'possedeQualDirigeantAgence'.
This class does not have an instance variable of the name possedeQualDirigeantAgence or _possedeQualDirigeantAgence, nor a method of the name setPossedeQualDirigeantAgence or _setPossedeQualDirigeantAgence
at com.webobjects.foundation.NSKeyValueCoding$DefaultImplementation.handleTakeValueForUnboundKey(NSKeyValueCoding.java:1399)
at com.webobjects.eocontrol.EOCustomObject.handleTakeValueForUnboundKey(EOCustomObject.java:1562)
at com.wounit.rules.MockEditingContext.insertSavedObject(MockEditingContext.java:238)
at com.wounit.rules.MockEditingContext$DummyFacade.insert(MockEditingContext.java:88)
at com.wounit.rules.AnnotationProcessor.initializeObject(AnnotationProcessor.java:167)
at com.wounit.rules.AnnotationProcessor.process(AnnotationProcessor.java:205)
at com.wounit.rules.MockEditingContext.before(MockEditingContext.java:149)
at com.wounit.rules.AbstractEditingContextRule$1.evaluate(AbstractEditingContextRule.java:138)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:208)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:158)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:86)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:95)

Exception when cascade deleting not saved objects

Suppose Foo has a relationship to Bar marked to cascade delete. The following code produces an exception.

@test
public void cascadeDelete() {
Foo foo = Foo.createFoo(ec);

foo.setBar(Bar.createBar(ec));
foo.deleteObject();

ec.saveChanges();
}

InvocationTargetException testing partial entities

This is similar to the issue I reported in #32 (in that it occurs with the exact same test I described there), but it's a different looking stack trace now.

I may have contributed to some confusion here, in that I pulled the test described in #32 from my test suite altogether, and then described a different partials-related problem (whereby attributes added by the augmented entities weren't being recognised as merged into the base entity) which was completely fixed in the recent 1.2.3 release.

What I'm seeing now is an InvocationTargetException trying to test the base class at the framework level. I'll reproduce here the code from #32, as it's the same:

public class UserTest {
    @Rule
    public MockEditingContext ec = new MockEditingContext("Ident");

    @Test
    public void createUser() {
        User u = User.createUser(ec, "password", "username");
        confirm(u, canBeSaved());
        return;
    }
}

Worse, the problem is non-deterministic: sometimes this test will pass, sometimes it will fail. When it fails, this is the current stack trace:

com.webobjects.foundation.NSForwardException [java.lang.reflect.InvocationTargetException] null:java.lang.reflect.InvocationTargetException
    at com.webobjects.foundation._NSUtilities._explainInstantiationException(_NSUtilities.java:626)
    at com.webobjects.foundation._NSUtilities.instantiateObjectWithConstructor(_NSUtilities.java:665)
    at com.webobjects.eoaccess.EOEntityClassDescription.createInstanceWithEditingContext(EOEntityClassDescription.java:242)
    at com.webobjects.eoaccess.EOUtilities.createAndInsertInstance(EOUtilities.java:861)
    at com.wounit.rules.AbstractEditingContextRule$UnderTestFacade.create(AbstractEditingContextRule.java:72)
    at com.wounit.rules.AnnotationProcessor.createEOForType(AnnotationProcessor.java:49)
    at com.wounit.rules.AnnotationProcessor.initializeObject(AnnotationProcessor.java:172)
    at com.wounit.rules.AnnotationProcessor.process(AnnotationProcessor.java:205)
    at com.wounit.rules.AbstractEditingContextRule.before(AbstractEditingContextRule.java:182)
    at com.wounit.rules.MockEditingContext.before(MockEditingContext.java:147)
    at com.wounit.rules.AbstractEditingContextRule$1.evaluate(AbstractEditingContextRule.java:162)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    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)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.webobjects.foundation._NSUtilities.instantiateObjectWithConstructor(_NSUtilities.java:659)
    ... 24 more
Caused by: java.lang.NullPointerException
    at com.webobjects.eoaccess.EOModel.createPrototypeCache(EOModel.java:631)
    at com.webobjects.eoaccess.EOModel.prototypeAttributeNamed(EOModel.java:699)
    at com.webobjects.eoaccess.ERXModel.prototypeAttributeNamed(ERXModel.java:290)
    at com.webobjects.eoaccess.EOAttribute.<init>(EOAttribute.java:998)
    at com.webobjects.eoaccess.EOEntity.attributes(EOEntity.java:816)
    at com.webobjects.eoaccess.EOEntity.attributeNamed(EOEntity.java:789)
    at com.webobjects.eoaccess.EOEntity.classProperties(EOEntity.java:1098)
    at com.webobjects.eoaccess.EOEntity._propertyDictionaryInitializer(EOEntity.java:3321)
    at com.webobjects.eoaccess.EOEntity._newDictionaryForProperties(EOEntity.java:3667)
    at com.webobjects.eoaccess.EOEntityClassDescription._newDictionaryForProperties(EOEntityClassDescription.java:88)
    at com.webobjects.eocontrol.EOGenericRecord.__setClassDescription(EOGenericRecord.java:111)
    at com.webobjects.eocontrol.EOGenericRecord.__setClassDescription(EOGenericRecord.java:100)
    at com.webobjects.eocontrol.EOGenericRecord.<init>(EOGenericRecord.java:73)
    at er.extensions.eof.ERXGenericRecord.<init>(ERXGenericRecord.java:103)
    at er.extensions.partials.ERXPartialGenericRecord.<init>(ERXPartialGenericRecord.java:28)
    at net.logicsquad.access.model._User.<init>(_User.java:20)
    at net.logicsquad.access.model.User.<init>(User.java:14)
    ... 29 more

Note that that is different to the stack trace in #32.

So, to re-iterate, 1.2.3 completely solves the initialisation-related issue with merging of properties down to the base class. But the problem of testing just the base classes seems to persist.

Henrique, I'm going to send you my framework and its tests out of band in the hope you can pinpoint the problem quickly.

Creating a primary key uses the actual database context

using the method ERXEOControlUtilities.newPrimaryKeyDictionaryForEntityNamed
with a MockEditingContext fetches the models actual database context instead of a fake one, actually increasing the primary key sequence in the database

@UnderTest annotation to create the EO being tested

When testing an EO, usually a basic setup have to be made in order to test an EO:

private EO eo;

@before
pubic void setup() {
eo = EO.createEO(ec);
}

The @undertest annotation could be used to reduce the amount of boilerplate code.

@undertest private EO eo;

The MockEditingContext and the TemporaryEditingContext rules creates and inserts the EO automagically.

The annotation is also useful as a sanity check. Unit tests usually will have only one field annotated with @undertest.

Testing from the command line does not work

test:
[junit] Testsuite: net.starhealthcare.sffoundation.model.SFGoalTest
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 1.3 sec
[junit] ------------- Standard Error -----------------
[junit] log4j:WARN No appenders could be found for logger (er.extensions.eof.ERXEC).
[junit] log4j:WARN Please initialize the log4j system properly.
[junit] [2011-9-22 12:11:56 CEST] Couldn't load properties file: /Users/marius/WebObjects.properties at path: /Users/marius
[junit] [2011-9-22 12:11:56 CEST] Couldn't load properties file: /Users/marius/WebObjects.properties at path: /Users/marius
[junit] ------------- ---------------- ---------------
[junit] Testcase: shouldCloneCorrectlyWhenEditingAGoal(net.starhealthcare.sffoundation.model.SFGoalTest): Caused an ERROR
[junit] java.lang.reflect.InvocationTargetException
[junit] com.webobjects.foundation.NSForwardException [java.lang.reflect.InvocationTargetException] null:java.lang.reflect.InvocationTargetException
[junit] at com.webobjects.foundation._NSUtilities._explainInstantiationException(_NSUtilities.java:626)
[junit] at com.webobjects.foundation._NSUtilities.instantiateObjectWithConstructor(_NSUtilities.java:665)
[junit] at com.webobjects.eoaccess.EOEntityClassDescription.createInstanceWithEditingContext(EOEntityClassDescription.java:242)
[junit] at com.webobjects.eoaccess.EOUtilities.createAndInsertInstance(EOUtilities.java:861)
[junit] at com.wounit.rules.AbstractEditingContextRule$UnderTestFactory.create(AbstractEditingContextRule.java:61)
[junit] at com.wounit.rules.AnnotationProcessor.process(AnnotationProcessor.java:88)
[junit] at com.wounit.rules.AbstractEditingContextRule.before(AbstractEditingContextRule.java:150)
[junit] at com.wounit.rules.MockEditingContext.before(MockEditingContext.java:142)
[junit] at com.wounit.rules.AbstractEditingContextRule$1.evaluate(AbstractEditingContextRule.java:130)
[junit] at org.eclipse.ant.internal.launching.remote.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
[junit] at org.eclipse.ant.internal.launching.remote.InternalAntRunner.run(InternalAntRunner.java:424)
[junit] at org.eclipse.ant.internal.launching.remote.InternalAntRunner.main(InternalAntRunner.java:138)
[junit] Caused by: java.lang.reflect.InvocationTargetException
[junit] at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
[junit] at com.webobjects.foundation._NSUtilities.instantiateObjectWithConstructor(_NSUtilities.java:659)
[junit] Caused by: java.lang.IllegalStateException: Unable to get the name of the class to instantiate for the adaptor framework JavaJDBCAdaptor. The possible causes for this error are: the adaptor framework is not installed on your system, the adaptor framework is not linked into your application, or the info dictionary for this adaptor is corrupted.
[junit] at com.webobjects.eoaccess.EOAdaptor.classForAdaptorNamed(EOAdaptor.java:264)
[junit] at com.webobjects.eoaccess.EOAdaptor.adaptorWithName(EOAdaptor.java:287)
[junit] at com.webobjects.eoaccess.EOAdaptor.adaptorWithModel(EOAdaptor.java:312)
[junit] at com.webobjects.eoaccess.EOModel.createPrototypeCache(EOModel.java:624)
[junit] at com.webobjects.eoaccess.EOModel.prototypeAttributeNamed(EOModel.java:699)
[junit] at com.webobjects.eoaccess.EOAttribute.(EOAttribute.java:998)
[junit] at com.webobjects.eoaccess.EOEntity.attributes(EOEntity.java:816)
[junit] at com.webobjects.eoaccess.EOEntity.attributeNamed(EOEntity.java:789)
[junit] at com.webobjects.eoaccess.EOEntity.classProperties(EOEntity.java:1098)
[junit] at com.webobjects.eoaccess.EOEntity._propertyDictionaryInitializer(EOEntity.java:3321)
[junit] at com.webobjects.eoaccess.EOEntity._newDictionaryForProperties(EOEntity.java:3667)
[junit] at com.webobjects.eoaccess.EOEntityClassDescription._newDictionaryForProperties(EOEntityClassDescription.java:88)
[junit] at com.webobjects.eocontrol.EOGenericRecord.__setClassDescription(EOGenericRecord.java:111)
[junit] at com.webobjects.eocontrol.EOGenericRecord.__setClassDescription(EOGenericRecord.java:100)
[junit] at com.webobjects.eocontrol.EOGenericRecord.(EOGenericRecord.java:73)
[junit] at er.extensions.eof.ERXGenericRecord.(ERXGenericRecord.java:99)
[junit] at net.starhealthcare.sffoundation.model.SFGenericRecord.(SFGenericRecord.java:19)
[junit] at net.starhealthcare.sffoundation.model.base._SFGoal.(_SFGoal.java:15)
[junit] at net.starhealthcare.sffoundation.model.SFGoal.(SFGoal.java:19)
[junit] Test net.starhealthcare.sffoundation.model.SFGoalTest FAILED

Does TemporaryEditingContext support Many-To-Many relationships?

Hi hprange,

Thanks a log for the great library and your work. Unfortunately, I have an issue with many-to-many relationship and it's not clear for me where the cause might be, since it works for real database, but not in tests.

Could you please clarify whether many-to-many (flatten) relationships should work as expected?

Thanks.

Create collection of dummy objects

Some tests require more than one object of a type to verify the expected condition.

private NSArray foos;

@before
public void setup() {
foos = new NSMutableArray();

foos.add(ec.createSavedObject(Foo.class));
foos.add(ec.createSavedObject(Foo.class));

}

We could enhance the @dummy annotation to support this kind of feature out of the box.

@dummy(size=2)
private NSArray foos;

We can support NSArray, NSSet among other kinds of Collection.

The default value for the size parameter should be one.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.