• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Database testing and EOF; junit testrunner environment;
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Database testing and EOF; junit testrunner environment;


  • Subject: Re: Database testing and EOF; junit testrunner environment;
  • From: Christian Pekeler <email@hidden>
  • Date: Fri, 7 Jul 2006 19:16:12 -0600

I'd be interested to hear how you approach testing EOs. I can understand the motivation to exclude the database so that the test run quickly and hence can be run frequently. However, I usually find that very few of the interesting methods of my EOs can be tested without a network of other EO objects.

Some examples:

MyEO has has a dozen relationships to other EOs, many of which are mandatory in the model. I want to test a method foo() that only interacts with two of those relationships. So all I'm doing:

public void testFoo() {
MyEO myEO = (MyEO)mockEditingContext().createSavedObject (_MyEO.ENTITY_NAME);
myEO.addToAsRelationship(mockEditingContext().createSavedObject (_A.ENTITY_NAME));
myEO.addToAsRelationship(mockEditingContext().createSavedObject (_A.ENTITY_NAME));
B b = (B)mockEditingContext().createSavedObject(_B.ENTITY_NAME);
b.setSomethingNecessaryForFoo(...);
myEO.setBRelationship(b);
myEO.foo();
assert...
}
I.e. I don't concern myself with setting up the whole object graph. All I'm doing is setting up the absolute minimum for testing foo().


Now let's say foo()'s implementation calls bar(), which traverses a huge portion of the object graph and then returns a number. Still, all I want to test is foo(). So what I usually do is taking control of bar() by creating an inner class inside the test case that inherits from MyEO and overwrites bar():

class TestMyEO extends MyEO {
  int bar;
  protected int bar() {
    return bar;
  }
}

public void testFoo() {
  TestMyEO myEO = new TestMyEO();
  mockEditingContext().insertSavedObject(myEO);
  myEO.bar = 0;
  ...
  // assert that foo does the right thing if bar returns 0

  myEO.bar = 30;
  // assert that foo does the right thing if bar returns 30
  ...
}

Now we still want to test bar() itself, and let's assume that the test would only be meaningful if lots of objects are involved, so then lets make it easy to setup those objects to keep the test method as short as possible:

void addNewCToMyEO(MyEO myEO, String name, int age) {
  C c = (C)mockEditingContext().createSavedObject(_C.ENTITY_NAME);
  c.setName(name);
  c.setAge(age);
  myEO.addToCsRelationship(c);
}

public void testBar() {
MyEO myEO = (MyEO)mockEditingContext().createSavedObject (_MyEO.ENTITY_NAME);
addNewCToMyEO(myEO, "abc", 3);
addNewCToMyEO(myEO, "def", 20);
addNewCToMyEO(myEO, "ghi", 9);
addNewCToMyEO(myEO, "abc", 1);
addNewCToMyEO(myEO, "def", 2);
addNewCToMyEO(myEO, "ghi", 5);
assertEquals(40, myEO.bar());
}


I find that with techniques like these I can test all of the test- worthy stuff in my business logic. Sometimes it's getting more complicated and I need to subclass several EOs and create objects of many EOs to setup a unit test. This is often a symptom for badly designed code (I'm just speaking about my own). The more experienced I get at TDD, though, the simpler and easier my test cases get.


Some times it is reasonable to create these by hand, but often this can be hundreds or thousands of objects.

Do you really need all those objects to unit test individual methods? If none of my examples would help, maybe you could explain one of your complex scenarios and we'll take a crack at making it testable without a DB.



So, although it makes the tests slow, I find it easier to read them from a known state in the database. Do you have two sets of tests, one quick, programmatic only set and one functional, database using, slow set?

I have unit tests that test units of code as much isolated as possible (i.e. with the fewest number of other objects involved), and without accessing the database. And then I'm working with a QA team that creates acceptance tests against a controlled database and also does exploratory testing against a production-data like database.



Christian



Attachment: smime.p7s
Description: S/MIME cryptographic signature

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >Database testing and EOF; junit testrunner environment; (From: Greg Brown <email@hidden>)
 >Re: Database testing and EOF; junit testrunner environment; (From: Christian Pekeler <email@hidden>)
 >Re: Database testing and EOF; junit testrunner environment; (From: Chuck Hill <email@hidden>)

  • Prev by Date: Re: WWDC WO Meet
  • Next by Date: Re: WWDC WO Meet
  • Previous by thread: Re: Database testing and EOF; junit testrunner environment;
  • Next by thread: webserver resources slow with error 501
  • Index(es):
    • Date
    • Thread