Class MyBusinessService

java.lang.Object
tutorial.domain.MyBusinessService

public final class MyBusinessService extends Object
This class makes use of several idioms which would prevent unit testing with more "conventional" mocking tools. Its usage is as simple as it gets: new MyBusinessService(data).doBusinessOperationXyz(). No need to make such classes stateless, or worse, singletons; instead, it's designed as a proper object.

One of those "untestable" idioms is the use of a static persistence facade (the Database class) for high-level database operations in the context of a thread-bound work unit. Since all interaction with the facade is through static methods, client classes cannot be unit tested with a tool which only supports mock objects. With JMockit, though, writing such a test is just as easy as any other (even easier, in fact, given that static methods don't require an instance of the mocked class at all).

Another idiom which runs against limitations of other mocking tools is the direct instantiation and use of external dependencies, such as the Apache Commons Email API, used here to send notification e-mails. As demonstrated here, sending an e-mail is simply a matter of instantiating the appropriate Email subclass, setting the necessary properties, and calling the send() method. It is certainly not a good use case for Dependency Injection (DI).

Finally, consider that application-specific classes like this one are inherently non-reusable in different contexts/applications; as such, they can and should be made final to reflect the fact that they are not supposed to be extended through inheritance. In the case of reusable base classes, which are specifically designed to be extended through inheritance, the judicious use of final for public and protected methods is important. (The description of the Template Method pattern in the "GoF" book explains why a properly designed template method should be non-overridable.) Unfortunately, the practice of designing for extension conflicts with the particular implementation approach employed by other mocking tools, which dynamically generate a subclass overriding all non-final methods in the mocked class in order to provide mocked behavior. For JMockit, on the other hand, whether a method or class to be mocked is final or not is irrelevant, as a radically different mocking approach is employed: class redefinition as provided by Instrumentation.redefineClasses(java.lang.instrument.ClassDefinition...).

  • Constructor Details

    • MyBusinessService

      public MyBusinessService(EntityX data)
  • Method Details

    • doBusinessOperationXyz

      public void doBusinessOperationXyz() throws org.apache.commons.mail.EmailException
      Throws:
      org.apache.commons.mail.EmailException