Re: Simplify (junit) testing in cayenne

From: Marcin Skladaniec (marci..sh.com.au)
Date: Thu Sep 06 2007 - 18:15:09 EDT

  • Next message: Mike Kienenberger: "Re: Simplify (junit) testing in cayenne"

    Hi
    Thank you for hints, they are useful. I'll try to use some of them,
    but my main concern is to test the client in ROP setup. As Mike and
    Tore mentioned, there are two levels of testing junit and integration
    test. Testing ROP application brings another dimension, with need to
    test client and server separately and together.
    Right now it is impossible to test client without running a server,
    and in our case if we want the client to connect we need to fake
    login process, start some side services etc. We have succeeded with
    those tests, but they are ugly and very limited.

    About testing MockDAO, or server side: Mike you mention that you use
    interfaces to define entities, and than implement that interface in
    MockEntities. I don't know if I get you right, but than you are not
    testing code in your Entity, but the implementation in the mocked-up
    one. I cannot see how this might work for testing lifecycle events or
    complex validation.

    In my current setup i subclass the entity with mockupentity and just
    by overriding getObjectId I have an almost fully working entity. The
    problem I have is that I cannot make them able to set relationships.
    I get a nullpointer in setReverseRelationship. I was trying to mock
    the entityresolver based on cayenne junit tests, but those tests
    subclass private classes, so I cannot use this approach. How could I
    overcome that ?

    I still think that cayenne could include a simplified junit testing
    API for different deployment options ("classic cayenne", ROP, web)

    Thanks
    Marcin

    On 07/09/2007, at 5:58 AM, Mike Kienenberger wrote:

    > Hmm. I got rid of the cleanup threads easily enough, but it didn't
    > really affect the memory usage. That's what I get for not using a
    > profiler. At least things are easier to read in the debugger
    > without all of those extra threads :-)
    >
    > On 9/6/07, Mike Kienenberger <mkienen..mail.com> wrote:
    >>> Why do you want all of that mocking stuff?
    >>
    >> Because what you described is an integration test, not a unit
    >> test :-)
    >>
    >> I have both -- the integration tests running against an in-memory
    >> hsqldb instance and unit tests running without needing to hit a
    >> database. However, running my integration tests still takes around
    >> 15 minutes.
    >>
    >> Configuring efficient integration tests is much more tricky. You
    >> either recreate everything which makes things take another order of
    >> magnitude to run, or you try to "clean up" the important record
    >> tables
    >> in setup.
    >>
    >> Configuring a unit test using mock objects is much faster -- you just
    >> configure your MockDAO to respond to expected method calls and
    >> poll it
    >> afterward to see if the expected method calls were called correctly.
    >>
    >> My other issue with integration tests is that I'm using Cayenne
    >> 1.1.4,
    >> and every setup() call to initialize Configuration creates a new
    >> PoolManagerCleanup thread which won't time out for 60 seconds. That
    >> makes my integration tests memory intensive -- currently about 1.4Gb
    >> of memory is required to run some 650+ tests. I just spent a couple
    >> of hours trying to figure out a nicer way to deal with this, but I
    >> haven't done so yet. I probably will need to subclass
    >> DriverDataSourceFactory and PoolManager.
    >>
    >> On 9/6/07, Tore Halset <halse..vv.ntnu.no> wrote:
    >>> Hello.
    >>>
    >>> My junit setup creates a database with all its tables and basic
    >>> schema and then all of the cayenne-related tests operate on that
    >>> temporary db. It is pretty much like cayenne junit tests before the
    >>> move to maven, but a bit simpler. The junit tests are started when a
    >>> developer wants to and periodically on our development server. It
    >>> tests everything with both PostgreSQL and Derby.
    >>>
    >>> Why do you want all of that mocking stuff?
    >>>
    >>> - Tore.
    >>>
    >>> On Sep 5, 2007, at 17:10, Mike Kienenberger wrote:
    >>>
    >>>> There's a few different ways to look at this.
    >>>>
    >>>> It's true that Cayenne doesn't easily support application unit
    >>>> testing.
    >>>>
    >>>> However, I'm not sure it's entirely appropriate to do so.
    >>>>
    >>>> What I do is use a DAO pattern for my database operations. Then I
    >>>> mock up a DAO rather than the entire database layer. It's far
    >>>> easier
    >>>> to mock up "myTestingDAO.findUserByUserName()" than to mock up
    >>>> SelectQuery, DataNode, DataMap, DataContext, etc.
    >>>>
    >>>> I haven't quite reached this point in all of my projects, but my
    >>>> goal
    >>>> is to generate Interfaces for each of my Entities. If I have a
    >>>> User
    >>>> entity, then I create a User interface and use that exclusively
    >>>> outside of my DAO. The DAO returns User interface objects rather
    >>>> than User data objects.
    >>>>
    >>>> This then allows me to create a MockUser simply by implementing the
    >>>> User interface. For projects where I don't have entity
    >>>> interfaces,
    >>>> I subclass the User DataObject instead. This isn't quite as
    >>>> clean or
    >>>> workable, but it does help so long as you override every method.
    >>>>
    >>>> For creating Mock objects, I use the cayenne code generator the
    >>>> same
    >>>> way I use it for the DataObjects.
    >>>>
    >>>> I'm finding that there are still some places where integration
    >>>> testing
    >>>> is necessary to catch problems. In Cayenne 1.1.4, I've had an
    >>>> issue
    >>>> where I tried to create a local copy of a modified or a transient
    >>>> object and then commit an object with a relationship to it -- those
    >>>> kinds of problems can only be detected when using the real database
    >>>> layer unless your mock layer knows the quirks.
    >>>>
    >>>>
    >>>>
    >>>> On 9/4/07, Marcin Skladaniec (JIRA) <de..ayenne.apache.org> wrote:
    >>>>> Simplify (junit) testing in cayenne
    >>>>> -----------------------------------
    >>>>>
    >>>>> Key: CAY-862
    >>>>> URL: https://issues.apache.org/cayenne/browse/
    >>>>> CAY-862
    >>>>> Project: Cayenne
    >>>>> Issue Type: New Feature
    >>>>> Components: Cayenne Core Library
    >>>>> Affects Versions: 3.0
    >>>>> Environment: All
    >>>>> Reporter: Marcin Skladaniec
    >>>>> Assignee: Andrus Adamchik
    >>>>>
    >>>>>
    >>>>> Junit tests are becoming very important once the project reaches a
    >>>>> certain point. Cayenne has dozens of junit tests but writing a
    >>>>> junit test for cayenne based application is not easy at all.
    >>>>>
    >>>>> For me the main trouble is when there is no need to fetch or
    >>>>> commit something (like testing GUI or lifecycle events). I tried
    >>>>> to reproduce the tests found in cayenne,but always ended up with
    >>>>> problems with mocking up the context, datachannel,
    >>>>> entityResolver, altering the configuration to point to different
    >>>>> db etc.
    >>>>>
    >>>>> To solve that my idea was that one might specify a package in the
    >>>>> CayenneModeler, this package will than be populated with generated
    >>>>> a set of _MockupXXX extends XXX (like _MockupArtist extends
    >>>>> Artist, _MockupPainting extends Painting etc.) and a
    >>>>> MockupDataContext etc. There could be a second set of
    >>>>> _MockupEntities for ROP client.
    >>>>>
    >>>>> Another thing is to specify the testing environment with ease. I
    >>>>> think there should be also a possibility to create a "testing"
    >>>>> DataNode pointing to a different database than deployment, and for
    >>>>> the DataMap could be related to the real or testing DataNode at
    >>>>> the same time. To choose the testing environment a system param
    >>>>> like -Dcayenne.testing=TRUE could be utilised.
    >>>>> I might have missed something here: is there a simply way of
    >>>>> having two DataNodes for one DataMap ?
    >>>>>
    >>>>> I think that simplified testcase writing feature would be a great
    >>>>> advantage for Cayenne over any other ORM.
    >>>>>
    >>>>> --
    >>>>> This message is automatically generated by JIRA.
    >>>>> -
    >>>>> You can reply to this email to add a comment to the issue online.
    >>>>>
    >>>>>
    >>>>
    >>>
    >>>
    >>



    This archive was generated by hypermail 2.0.0 : Thu Sep 06 2007 - 18:15:55 EDT