You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cactus-user@jakarta.apache.org by "J. B. Rainsberger" <jb...@rogers.com> on 2004/05/25 19:58:16 UTC

Testing a MDB on its own

Jayaraman.Dorai@transplace.com wrote:

> I am not sure I understood the solution completely, let me explain my
> problem again.  May be I should read the books suggested.
> 
> There are 3 components a) the MDB (lets say MDB1)  which I want to test, b)
> the session ejb,  and c) another MDB  (lets say MDB2)  which the session
> ejb calls.
> 
> Now, if I call the extracted method in the MDB1 directly, it will make a
> further call to session ejb which in turns asynchronously calls MDB2. Both
> session ejb and MDB2 create records in the database. Now I want to test
> that the records are being properly created. The testXXX() method will
> succeed  for only the records created in the session ejb and will fail for
> the tests of  records created in MDB2 as the MDB2 may not have been
> completed. Now I have a situation where MDB1 did not fail but the test
> cases shows it has failed.
> 
> Will mock objects or the suggested techniques, help me test the MDB1
> completely?

To summarize:

MDB1 -> SessionEJB -> MDB2

You define success for MDB1 as "the right records are created in the 
database."

Now, it is possible for MDB1 to succeed, but your success condition not 
to occur: if, say, MDB2 fails.

Do you want your test for MDB1 to fail if only MDB2 fails? I say "no," 
because then it's not a test for MDB1, but rather an integration test.

NOTE: I AM NOT SAYING THAT INTEGRATION TESTS ARE BAD. I /am/ saying that 
you seem only to want to test MDB1, and so you do not want to write an 
integration test, as that test might fail even through MDB1 works.

THEREFORE, we need to redesign so that MDB1 can run without MDB2. This 
way we can test MDB1 separately without relying on the correctness of MDB2.

NOW, MDB1 uses JNDI to retrieve a component interface for SessionEJB. At 
some point, MDB1 invokes a method on SessionEJB /which is expected 
eventually to result in records being created in the database/. I don't 
know what that method is, but let's say it's doWork().

interface SessionComponent {
     void doWork() throws Exception;
}

The idea is that the SessionBean implements doWork() to send a message 
that you expect MDB2 to handle, leading it then to create records in the 
database.

THEREFORE, ASSUME THAT WHEN YOU INVOKE doWork(), THAT IT WILL CORRECTLY 
CREATE RECORDS IN THE DATABASE. You're not testing this right now. 
You're testing whether MDB1 does the right thing, which includes 
invoking SessionComponent.doWork().

My definition of success is now this: MDB1 should invoke 
SessionComponent.doWork() exactly once.

With mock objects, I can write that test:

[pseudocode, similar to jMock]
testMdb1 {
     sessionComponent = create mock for SessionComponent

     sessionComponent.expect("doWork" invoked 1 time with no parameters, 
returning nothing)
     sessionComponent.readyToGo()

     message = create mock for Message
     message.expect(whatever methods you need to invoke to retrieve 
data, returning fake data)
     message.readyToGo()

     mdb1 = new MessageDrivenBean1()
     mdb1.processMessage(message, sessionComponent)

     sessionComponent.verify()
}

To make this test pass, I need to redesign MDB1 the way I discussed earlier.

[pseudocode]
class MessageDrivenBean1 ... {
     public void onMessage(Message message) {
         sessionComponent = lookup session EJB with JNDI
         processMessage(message, sessionComponent)
     }

     public void processMessage(Message message, SessionComponent 
sessionComponent) {
         do the real work
     }
}

Now you don't have to drag JNDI, the database or the EJB container into 
the test: you can test MDB1 on its own! As far as the JNDI lookup goes, 
that's still untested, but the majority of the real work /is/ tested, 
and that's a very good start. Once you're comfortable with this, we can 
talk about good strategies for testing the JNDI lookup. (Hint: 
www.mockejb.org)

Better?

[BTW: This is /almost/ an excerpt from my book, so that gives you an 
idea what's in there.]
-- 
J. B. Rainsberger,
Diaspar Software Services
http://www.diasparsoftware.com :: +1 416 791-8603
Let's write software that people understand