Which mocking framework is preferred for testing EJB's (specifically Message Driven Beans), I'm looking at MockObjects, easyMock, MockEJB and mockito but open all.
I've not used mocking framework before and particularly interested in low learning curve / great getting started guide.
I should clarify, using EJB 2.
A framework specifically build for this is Arquillian - http://www.jboss.org/arquillian.
This lets you test in-container via JUnit. You can test individual beans or larger collections. You can provide mocks by simply packaging other implementations in the test archive.
When using Java EE 6 (JBoss AS 6, Glassfish V3), you can run the container in embedded mode which simplifies matters and saves you in run-time overhead.
EJB2 is notoriously difficult to test though. If possible I suggest you drop it completely in favor of EJB3.x, but of course this might not be an option for you.
It's not a mocking framework, but you might like to have a look at OpenEJB, which is a lightweight EJB container suitable for, amongst other things, use in unit tests. It will save you having to mock the container's interfaces, and you can still mock interfaces to other components.
If you're using EJB 3.x, then is heavily interface-based, and so your usual run-of-the-mill mocking frameworks will do just fine for unit tests; the fact that the code is used by the EJB framework isn't really relevant.
EJB 2.x is a different (and ugly) kettle of fish, though, since it doesn't conform to any of the usual sane rules of software design. Your best bet there is probably a framework like Cactus.
Related
I'm currently thinking about expanding unit tests for a server and a client application. Mockito is already in use and - I think - very well suited for the task at hand. However, as the Mockito documentation itself admits:
Mockito is not an dependency injection framework, don't expect [the #InjectMocks annotation] to inject a complex graph of objects be it mocks/spies or real objects.
The server-side of course already has CDI via annotations at some places, the client will probably be extended in some place to use CDI for JavaSE in the near future. There is/will be a wild mix of field- and constructor-injection + #postconstruct methods, which is already too complicated for Mockito. So I'm looking for something that will allow me to easily use CDI annotations to inject Mockito's mocks/spies/real objects where needed.
Can Mockito's functionality be expanded via plugins or something similar to enable a dependency resolution closer to what is specified by CDI (I don't think I need the full spec, but something closer to it)? Is there another library that integrates with Mockito and JUnit5 that does that?
weld supports this out of the box, specifically by weld-junit. It supports both junit4 and junit5. In both cases one can define producer methods for the required injection points in which one can freely use mockito or powermock or any other mocking mechanism to create mocks which weld then injects into the test object.
If you wish to mock EJB/CDI beans with OpenEJB, you can do it very easily:
http://tomee.apache.org/master/examples/rest-applicationcomposer-mockito.html
cdi-unit and ioc-unit have modules which support that.
Just add
#Produces
#Mock
ClassName mockedObject;
and the framework will make it an injectable Bean.
I'm not a very experienced software engineer. We have a very large application that consists of 40 plus projects. We use EJB 3.0, Struts 1 framework.
Right now, we have issue unit testing Service layers having dependency on more than one beans. Because we can only inject one of them without a running server due to not having a container.
I've read that EJB3.1 does not have this issue. What changes in EJB3.1 has made it immune to this problem?
Also if you can direct me to a work around or a solution, I'd really appreciate it.
Another solution is to move from ANT to Maven, but I read in another question that it's not a good idea for very big projects like ours.
So my questions are:
Is there absolutely no solution to this?
What makes this dependency injection issue for unit testing work in Spring and Maven?
If giving multiple solutions, would appreciate it if you could also tell the scope of the changes required for the solution and effort it requires in phases of the project in general (analysis, design, testing, implementation, etc.)
Maven is definitely better than ant, and well used for big projects.
You can mock in dependencies, during unit tests.
EJB3.1 provides an embeddable container, which makes it easy to perform integration tests.
I recently started as a freelancer on my current project. One of the thing I threw myself on, was the failing Jenkins build (it was failing starting from April 8th, a week before I started here).
Generally speaking, you could see a buttload of DI issues in the log. First thing I did, was get all tests to work in the same way, starting from the same application context.
They also implemented their own "mocking" thing, which seemed to fail to work correctly. After a discussion with the lead dev, I suggested to start using Springockito. (for a certain module, they needed mocking for their integration testing -- legacy reasons, which can't be changed)
Anyway, stuff started failing badly after that. A lot of beans which were mocked in the test, simply weren't mocked, or weren't found or whatever. Typically, it would fail on the loading of the application context, stating that one or another bean was missing.
I tried different stuff and different approaches, but in the end, only the thing I most feared would work: add #DirtiesContext to every single test. Now, the maven build is starting to turn green again, tests start doing what they are supposed to do. But I am reloading the Spring context each and every time, which takes time - which is all relative, since the context is loaded in about 1 - 2 seconds.
A side note to this story is that they've upgraded to Hibernate 4, and thus to Spring 3.2. Previously, they were using an older version of Spring 3. All tests were working back then, and the #DirtiesContext thing was not necessary.
Now, what worries me the most, is that I can't immediately think of an explanation for this weird behaviour. It almost seems that Springs context is dirtied, simply by launching a test which uses #Autowired beans. Not all tests are using Mocks, so it can't be that.
Does this sound familiar to anyone? Has anyone had the same experiences with integration testing with (the latest version of) Spring?
On Stackoverflow, I've found this ticket: How can a test 'dirty' a spring application context?
It seems to pretty much sum up the behaviour I'm seeing, but the point is that we're autowiring services/repositories/..., and that we don't have any setters on those classes whatsoever.
Any thoughts?
Thanks!
To answer my own question, the secret was in the Spring version. We were using Spring 3.1.3, whereas I presumed they were using Spring 3.2 (they were constantly speaking about a recent upgrade of the Spring version).
The explanation was here, a blog post I stumbled over in my hunt to get it fixed: Spring Framework 3.2 RC1: New Testing Features
And a copy paste of the relevant piece:
The use of generic factory methods in Spring configuration is by no means specific to testing, but generic factory methods such as EasyMock.createMock(MyService.class) or Mockito.mock(MyService.class) are often used to create dynamic mocks for Spring beans in a test application context. For example, prior to Spring Framework 3.2 the following configuration could fail to autowire the OrderRepository into the OrderService. The reason is that, depending on the order in which beans are initialized in the application context, Spring would potentially infer the type of the orderRepository bean to be java.lang.Object instead of com.example.repository.OrderRepository.
So, how did I solve this problem? Well, I did the following steps:
create a new maven module
filter out the tests which needed mocking. All the non-mocked test would run normallly in a Spring build, in a separate Failsafe run (I created a base-package "clean", and sorted them out like that)
Put all the mocked tests in a base package called "mocked", and make an additional run in Failsafe for the mocked tests.
Each mocked test is using Springockito, to create the mocks. I'm also using the Springockito annotations, to easily do a #ReplaceWithMock in place. Every mocked test is then annotated with #DirtiesContext, so the context is dirtied after each test, and the Spring context is reintroduced with each test.
The only reasonable explanation that I could give, is that the context is effectively being dirtied, because there is a framework (Springockito) which is taking over the management of the Spring beans from the Spring framework. I don't know if that's correct, but it's the best explanation I could come up with. That, in fact, is the definition of a dirty context, which is why we need to flag it as dirty.
Using this strategy, I got the build up and running again, and all tests are running ok. It's not perfect, but it's working, and it's consistent.
I am trying to use Guice for a test framework based on TestNG. This frameworks analyzes the test class for dependencies and provides them eliminating the need to build them in tests.
Guice is all about injection and I think is a good fit for the framework. But the question is how do I define bindings after I have created the injector? This is needed because tests may override bindings to substitute default implementations with mocks.
Besides that, I want to guess the implementation at runtime in some cases based on class names conventions. Sounds like Just-in-type binding feature. But how do I provide my own just-in-time binding provider?
That kind of dynamic behaviour isn't supported out-of-the-box, but you can achieve a lot with module rewriting. Take a look at Guiceberry, which already implements mock-substitution for JUnit tests. (And consider submitting a TestNG patch to them, they'd love that!)
I've been asked to work on changing a number of classes that are core to the system we work on. The classes in question each require 5 - 10 different related objects, which themselves need a similiar amount of objects.
Data is also pulled in from several data sources, and the project uses EJB2 so when testing, I'm running without a container to pull in the dependencies I need!
I'm beginning to get overwhelmed with this task. I have tried unit testing with JUnit and Easymock, but as soon as I mock or stub one thing, I find it needs lots more. Everything seems to be quite tightly coupled such that I'm reaching about 3 or 4 levels out with my stubs in order to prevent NullPointerExceptions.
Usually with this type of task, I would simply make changes and test as I went along. But the shortest build cycle is about 10 minutes, and I like to code with very short iterations between executions (probably because I'm not very confident with my ability to write flawless code).
Anyone know a good strategy / workflow to get out of this quagmire?
As you suggest, it sounds like your main problem is that the API you are working with is too tightly coupled. If you have the ability to modify the API, it can be very helpful to hide immediate dependencies behind interfaces so that you can cut off your dependency graph at the immediate dependency.
If this is not possible, an Auto-Mocking Container may be of help. This is basically a container that automatically figures out how to return a mock with good default behavior for nested abstractions. As I work on the .NET framework, I can't recommend any for Java.
If you would like to read up on unit testing patterns and best practices, I can only recommend xUnit Test Patterns.
For strategies for decoupling tightly coupled code I recommend Working Effectively with Legacy Code.
First thing I'd try to do is shorting the build cycle. Maybe add in the options to only build and test the components currently under development.
Next I'd look at decoupling some of the dependencies by introducing interfaces to sit between each component. I'd also want to move the coupling out in the open most likely using Dependency Injection. If I could notmove to DI I would have two ctors, on no-arg ctor that used the service locator (or what have thee) and one injectable ctor.
the project uses EJB2 so when testing, I'm running without a container to pull in the dependencies I need!
Is that without meant to be a with? I would look at moving as much into POJOs as you can so it can be tested without needing to know anything EJB-y.
If you project can compile with Java 1.5 you shoul look at JMock? Things can get stubbed pretty quickly with 2.* version of this framework.
1.* version will work with 1.3+ Java compiler but the mocking is much more verbose, so I would not recommend it.
As for the strategy, my advice to you is to embrace interfaces. Even if you have a single implementation of the given interface, always create an interface. They can be mocked very easily and will allow you much better decoupling when testing your code.