[jboss-user] [JBoss Seam] - Possible to write a rollback SeamTest?
RobJellinghaus
do-not-reply at jboss.com
Tue Jul 11 04:03:41 EDT 2006
OK, so pardon my lack of clue here. This is kind of a minor conundrum, but maybe someone knows the answer off the top of their head.
I am writing a base class for versioned objects. These versioned objects can make (dynamically) immutable copies of themselves. I call these copies "snapshots".
To ensure that my code doesn't modify the supposed-to-be-immutable snapshots, I have a @PreUpdate method in the base class which checks to see if the object is a snapshot (which is true iff its "replicatedChangeset" field is non-null). If it is, the @PreUpdate throws a SnapshotModifiedException.
@Entity
| @Inheritance(strategy=InheritanceType.JOINED)
| public abstract class RepObject {
| ...
| private Changeset replicatedChangeset;
| ...
| @PreUpdate
| private void checkUpdate () {
| log.debug("Calling checkUpdate on " + this + "...");
| if (replicatedChangeset != null) {
| throw new SnapshotModifiedException(this);
| }
| }
| ...
| }
SnapshotModifiedException:
@ApplicationException(rollback=true)
| public class SnapshotModifiedException
| extends RuntimeException
| {
| RepObject snapshot;
|
| public SnapshotModifiedException(RepObject snapshot) {
| this.snapshot = snapshot;
| assert snapshot.getReplicatedChangeset() != null;
| }
| ...
| }
This all works fine, actually.
So now, naturally enough, I want to write a SeamTest that tries to modify a snapshot object, and then fails if the modification is successful, and passes if the modification blows up as expected. Here's my attempt:
@Override
| protected void updateModelValues()
| {
| entityManager = (EntityManager) Component.getInstance("entityManager", true);
| changesetLog = (ChangesetLog) Contexts.getApplicationContext().get("changesetLog");
| }
|
| @Override
| protected void invokeApplication()
| {
| // ... get a list of snapshot objects in the List priorBlogPosts ...
| try {
| BlogPost prior1 = priorBlogPosts.get(0);
| prior1.setTitle("changedTitle"); // shouldn't change a snapshot!
|
| // trigger the @PreUpdate check
| entityManager.flush();
|
| assert false; // plan to die if we get this far; should get exception from the flush
| } catch (RuntimeException e) {
| log.info("Got expected exception from attempted snapshot update", e);
|
| // rethrow e... since it's marked as @ApplicationException(rollback=true), should roll back peacefully?!
| throw e;
| }
| }
Now, this obviously doesn't work, because I rethrow the exception, so the test dies. (Note that the exception is not a SnapshotModifiedException, it's an InvocationTargetException wrapping a SnapshotModifiedException. Oh well.)
But what should I do instead? If I swallow the exception, the test will still die, because it will try to flush again and fail. I think I want to do setRollbackOnly. But I don't actually know how to *do* setRollbackOnly from inside a SeamTest. The only syntax I see for it is (from the dvd example):
@Resource
| SessionContext ctx;
| ...
| ctx.setRollbackOnly();
But this can't be done from a SeamTest. If I just change my test to:
@Resource
| SessionContext ctx;
| ...
| } catch (RuntimeException e) {
| log.info("Got expected exception from attempted snapshot update", e);
|
| ctx.setRollbackOnly();
| }
Then I get a NullPointerException because SeamTests don't seem to support @Resource injection, so ctx is null. So how do I get a hold of a javax.ejb.SessionContext in my SeamTest to make it roll back peacefully?
Basically I'm between a rock and a hard place:
1) If I swallow the exception, then the test blows up when it tries to commit, because it flushes again and hits the exception again.
2) If I rethrow the exception, then the test blows up because an exception thrown out a test causes a test failure.
3) I can't do "ctx.setRollbackOnly();" in my catch clause because I don't know how to inject or otherwise obtain a javax.ejb.SessionContext in my test.
Obviously I could just punt on this whole test, but this is really important functionality in my little framework and I want a test for it :-)
Clues, anyone? There's probably some dead simple way to get the SessionContext from inside a SeamTest... I just can't imagine what it is!
Thanks!
Cheers,
Rob
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3956875#3956875
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3956875
More information about the jboss-user
mailing list