Bala
Bala

Reputation: 1203

unit testing EJB 3.1 - why mock container services

What is the advantage of mocking the container services in Unit testing of EJB 3.1?

The probable answers I get when I think about it are,

  1. It improves the performance of the tests.
  2. It does not abide by the rules of Unit testing as there is a lot of interactions with other APIs. (Please provide your views on this)

Other than these, do you think there are other advantages?

As many of you may know, it is possible to test some of the services provided by the container, like persistence, transaction management (eg. using Bitronix), messaging (eg. using Apache ActiveMQ and in-memory JNDI) out of the container in your own JVM. Still there is an argument that it is integration testing and unit testing should not be done that way.

According to me, if you can have a good performance in your tests, it is fine to use these third party implementations for unit testing because you do not have to spend too much time in mocking and mocking is heavily subject to developer errors. If a developer does not have a good understanding of mocking, he might end up mocking everything or in other words misusing mocking to turn the tests "green". Is this right? (Please provide your views on this)

After all, I never got any solid definition of unit testing :-). It depends on the author. Some define "unit" as the smallest unit that can be tested and some define "Depending on the context, these could be the individual subprograms or a larger component made of tightly related units."

Thanks.

Upvotes: 1

Views: 348

Answers (1)

Tom Anderson
Tom Anderson

Reputation: 47233

If you have code which uses container services, then to test it, you will need to either mock those services, or use a real implementation. You have to do one or the other: without some implementation of the services, your code will not run, and so cannnot be tested.

Sometimes, you can refactor your code to remove the direct dependency on the container services, which will also remove the need to mock those services. But not always.

Mocking the container services provides more isolation than using a real implementation. It also gives you more control over and insight into the execution of your code. However, it also involves writing more code, and with it, more risk of introducing bugs (bugs in mocks, that can translate directly into bugs in application code).

There are some times when mocking definitely makes sense. For example, if you want to write a test that checks that your code is making the correct calls on UserTransaction, then that it much easier to do by mocking than by trying to instrument a real transaction monitor. If you want to write a test that checks that your code handles a particular SQLException correctly, then that is almost impossible to do without a mock.

Beyond those cases, as you point out, it is possible to write tests using the real services, or mocking them. As i think you have realised, the orthodox unit testing approach would be to mock them, or, in fact, to wrap them, and then mock the wrappers.

Whether this is actually necessary, or a good idea, is very much open to debate.

StackOverflow is not supposed to be for subjective questions, or for debates or discussions, so i hesitate to go into my opinion on this. Suffice to say that it is the same as i suspect yours to be - that the orthodox 'mock everything that moves' approach is unnecessary and harmful, and we would be much better off writing tests with less mocking, covering larger areas of real code. After all, real code is what we're going to ship to users, so why not test it?

Upvotes: 3

Related Questions