Functional testing Java-EE applications often requires validating the behavior of your business logic in interaction with one or more surrounding systems. Usually it’s not desirable to actually interact with these systems from your automated functional test cases as this can introduce non-deterministic behavior and jeopardizes repeatability – two very important aspects of solid testing.
In Part 1 we took a look at the advantages TestEE.fi offers for functional testing Java-EE applications and concluded with a bare-bones example of how to write your first TestEE.fi based JUnit 4 test. The sample code in Part 1 already gave a small hint on how mocking classes in your tests works and in this second installment we take a closer look at how in TestEE.fi mocking with both Mockito and EasyMock is a first class citizen.
If you add the “testeefi-junit4-all” dependency to your project, you have the Mockito integration already in your classpath. For EasyMock you have to add another entry to your project’s dependencies:
For Gradle the snippet looks like this:
In order to understand how mocking is used in TestEE.fi let me introduce some example classes first and then show both the usage of Mockito and EasyMock to replace certain EJBs or CDI managed beans with mocks at test runtime.
Let’s assume we want to write a program that notifies us when a website is not available. I will distribute this logic into four classes:
- HttpCheckingAdapter: performs a HTTP request to check if some URL is available.
- EmailDispatchAdapter: sends E-Mails.
- AlertingService: orchestrates the other two beans in order to fulfill the use case.
- AlertingFacade: being a professional developer I hide my business logic behind a facade that performs cross-cutting concerns like transactions or logging.
Testing the application with mocks
Now that we have the sample code established we continue to the actual test class. I will write the test using the facade class as “test subject” (as you should when you’re testing your business use cases) and I will mock away both Adapter classes which would normally require access to external systems – unsuitable for repeatable independent testing of your application.
It might surprise you (or not) that the test class (at least until this point) looks the same regardless whether you are using Mockito or EasyMock. Both provide a @Mock annotation and use it in basically the same way. Consequently the only difference for this test class is the import statement for the @Mock annotation as they (unsurprisingly) reside in different packages for the two mocking libraries.
Let’s take a quick look at what’s going to happen here when we run the test:
- A new instance of your test class is instantiated for the test method (this happens for each test method and this is standard JUnit behavior)
- Mocks are created for the two fields annotated with @Mock and injected into the test class instance
- An instance of AlertingFacade is instantiated and injected into your test case
- An instance of AlertingService is instantiated and injected into AlertingFacade
- The two mocks are injected instead of actual bean instances in AlertingService
- The test method is executed
Notice how in step 4 the instantiation and injection of unmocked beans is performed as it would at runtime by the application server. This is due to TestEE.fi wiring your application as it would run in production and only taking a special detour for mocked classes – it supports the full range of CDI dependency injection mechanisms (such as @Produces methods, constructor injection, qualifier annotations etc.) and even advanced EJB style dependency injection patterns like circular references or self-injection.
Now everything is ready for setting up some behavior for our mocks and actually testing our business logic. As the actual implementation of the test method differs between the two mocking libraries I will start with the Mockito incarnation of our test method and will the move on to the EasyMock implementation.
Testing in TestEE.fi with Mockito
Since this is not a tutorial on how Mockito works in detail I won’t dive too deep into the actual test code implementation. Note however how Mockito aligns nicely to the BDD-style Given-When-Then pattern (which I really like) and allows us to express the behavior we expect from our mocks in a very clean and concise fashion.
Testing in TestEE.fi with EasyMock
As with Mockito, since this is not an in-depth tutorial on EasyMock, we’ll leave it at simply presenting the code – for this simple example use-case it’s rather self-explanatory anyway. Note however how, in contrast to the BDD-style of the previous example, EasyMock relies on a record-replay-verify pattern that feels more like a movie script your code has to follow.
Both styles of mocking have their up- and downsides and it’s good to know that whichever you need or prefer, TestEE.fi makes it easy to use either one of them (or even both of them) in your tests.
In this quick installment you’ve learned how to use both Mockito and EasyMock together with TestEE.fi and you’ve seen first hand how mocking integrates in a very natural fashion with CDI injection. The example we’ve used demonstrated the primary purpose of mocking when you’re functional testing whole use-cases: the ability to replace external systems with customizable and reproducible behavior.
The source code of the sample application on which the examples above are based can be found here.
If you want to know more about advanced testing with TestEE.fi, be sure to check out the other posts of this series to get you up to speed quickly: