-
1. Re: Unit Testing and EntityManager injection
gavin.king Oct 4, 2005 2:46 AM (in response to mpancotti)You have to write that method yourself. It's just standard EJB3 stuff, not Seam-specific.
-
2. Re: Unit Testing and EntityManager injection
lcoetzee Jan 16, 2006 8:23 AM (in response to mpancotti)Is there an example of it somewhere ?
(I have managed to get the integration test running using the microcontainer, but would ideally like to build unit tests as well).
Thanks
Louis -
3. Re: Unit Testing and EntityManager injection
gavin.king Jan 18, 2006 1:56 AM (in response to mpancotti)Check the EJB3 persistence spec, there are examples there.
-
4. Re: Unit Testing and EntityManager injection
lcoetzee Jan 18, 2006 10:42 AM (in response to mpancotti)Thanks for the pointer.
Based on what I saw in the spec (after a very quick scan) I have implemented it as follows (assuming that the trySeam1Entity has been configured in my persistence.xml):public class BeginWithFactoryTestNG { private static EntityManagerFactory emf = null; public EntityManagerFactory getEntityManagerFactory() { if (emf == null) { emf = Persistence.createEntityManagerFactory("trySeam1Entity"); } return emf; } @Test public void testPersist() { EntityManager em = getEntityManagerFactory().createEntityManager(); assert em != null; FElement fe = new FElement(); fe.setValue("Gavin is King ;-)"); em.getTransaction().begin(); em.persist(fe); em.flush(); em.getTransaction().commit(); em.close(); } @Test public void testRetrieve() { EntityManager em = getEntityManagerFactory().createEntityManager(); . . } }
Seems to work OK, so hopefully I haven't missed the bus completely !
Thanks
Louis -
5. Re: Unit Testing and EntityManager injection
emsa Jan 19, 2006 5:10 AM (in response to mpancotti)Maybe this is a pure ejb3 question but I cannot find how to to this:
I want to replace the EntityManager with a mocked EntityManager so that
my EntityManager is used for all@PersistenceContext
injections.
How would I do that? Any pointers appreciated.
Thanks,
/Magnus -
6. Re: Unit Testing and EntityManager injection
gavin.king Jan 19, 2006 5:33 AM (in response to mpancotti)What do you mean by a "mock" EntityManager. It is very unusual - but perfectly possible - to mock out an EM. But perhaps "mock" is not really what you mean...
-
7. Re: Unit Testing and EntityManager injection
emsa Jan 19, 2006 5:43 AM (in response to mpancotti)What I mean is I want to use a EntityManager that basically just returns what I tell it to return without accessing the database, this to test code given a test scenario without having to access a database.
One such "mock" is to make persist() just do nothing or make it fail ...
This would to very usefull when testing certain database inserts that needs a lot of data already in the database without having to populate the database in advance.
/Magnus -
8. Re: Unit Testing and EntityManager injection
gavin.king Jan 19, 2006 5:49 AM (in response to mpancotti)Oh OK, apologies, that is truly a mock.
So, just instantiate one and inject it into your components ;-) -
9. Re: Unit Testing and EntityManager injection
emsa Jan 19, 2006 7:06 AM (in response to mpancotti)Hmm ... yes ... not that I'm sure how to do that ... an example would be nice.
I would still like the test to run in the microcontainer so that some object still uses a "real" EntityManager, if that is this possible? When should I inject my EM so that the microcontainer doesn't inject its EM after mine?
Thanks,
/Magnus -
10. Re: Unit Testing and EntityManager injection
gavin.king Jan 19, 2006 7:14 AM (in response to mpancotti)Oh if you are running EEJB its a bit different. It seems to me very strange to do mocking when running integration tests though. I would recommend:
(1) Mocking for unit tests (no mc or EEJB)
(2) No mocking for integration tests (mc/EEJB) -
11. Re: Unit Testing and EntityManager injection
emsa Jan 19, 2006 8:04 AM (in response to mpancotti)Really? A concrete example of what I would like to do, would be to run the "RegisterTest" with a mocked em instance, to test that the session-bean-logic and the navigation flow is working as expected, but without actually insering anything into any database.
This (imho) should be very usefull if the "register.register()" call does some validation that needs testing and/or the data insertion into the database requires that data is already present in the database (roles, groups etc).
Do you in this case mean that I should run this test without mc/EEJB? If so how do I inject my mocked em?
Thanks
/Magnus -
12. Re: Unit Testing and EntityManager injection
gavin.king Jan 19, 2006 8:23 AM (in response to mpancotti)Well, the thing is, if you run inside MC, you would have to mock out the EM *inside* the MC. This is very easy to do with a plain MC, but not really with EEJB.
I would try asking in the EJB3 forum, perhaps I am missing something.
But I really think it is very wierd to mock the database in integration tests. It is much, much better to actually test that the data is getting all the way to the db.
Now for *unit* tests, all you do is just create an EM and set the attribute of your bean. Its trivial.
LoginAction la = new LoginAction();
la.setEntityManager(mockEntityManager);
la.login();
or whatever.
If you are using instvar injection rather than setter injection, just use reflection to do it. -
13. Re: Unit Testing and EntityManager injection
emsa Jan 19, 2006 10:39 AM (in response to mpancotti)
But I really think it is very wierd to mock the database in integration tests. It is much, much better to actually test that the data is getting all the way to the db.
I have to disagree, just because you want to test the interaction between two objects it does not necessarily mean that you (also) want to test the interaction with the database.
I guess that I can solve this quite nicely by running the tests where I don't want database interaction outside the mc by injecting my own em and also run another set of test inside the mc for database integration testing.
It would be nice if SeamTest could help with this ;-) but I can manage on my own ... maybe I'm the only one that want to do this ...
Thanks,
/Magnus -
14. Re: Unit Testing and EntityManager injection
emsa Jan 20, 2006 5:40 AM (in response to mpancotti)I'm back after some playing around and I could really use some pointers.
I have done some tests using SeamTest trying to use my own EM but I cannot get it to work. This is mainly because 'Component.getInstance()' returns a Proxy and therefore I cannot replace the EM in the returned instance. When setting my own instance in the Context no injection takes place so other variables that need values remains empty.
Is there any way to solve this? I have two ideas:
1. Patch SeamTest/Component (or?) so that the EM can be replaces.
2. Somehow force SeamTest/Component (or?) to inject values in the object that I set in the Context.
Even though I know that you don't like what I'm trying to do I would deeply appreciate some insightful help here.
Thanks,
/Magnus