Mockito can't mock EntityManager - jpa

I'm starting with Mockito, and after reading several examples doing this, I can't mock the javax.persistence.EntityManager. It gives me:
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: interface javax.persistence.EntityManager.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
Yes, indeed EntityManager is an interface, but why there's too many examples doing things like this...
this.em = Mockito.mock(EntityManager.class);
or this...
#Mock
EntityManager em;
... and it works?
I've tried changes a lot of thinks, like the annotations
#RunWith(PowerMockRunner.class)
or
#RunWith(MockitoJUnitRunner.class)
or
#ExtendWith(MockitoExtension.class)
Tried either removing the #Mock and doing with:
MockitoAnnotations.initMocks(this);
But none of that works.
I'm awareabout whether or not it's really necessary to mock the entitymanager, but I really want to know what's wrong.

Related

Common lib for EntityManager CDI

I have a common generic DAO in common lib. I want in each module which uses this DAO to initialize with its own persistence UNIT
public abstract class GenericDao implements IGenericDao {
#PersistenceContext(unitName = "XXXX")
private EntityManager entityManager;
and in other module
public class CarDao extends GenericDao{
I have lot of projects are using this generic DAO but each project have its own persistence unit.
Persitence unit are differents following the project where is used the common library
The point is i could not use POO with abstract getEntityManager injected in each micro servicies because in common project we have a history DAO common for all microservicies and for each one i have to retrieve the entityManager injected from the microservice
Am i doing wrong or well? and how set th epersistence unit in each project ? (each project have lot fo DAO and i don't want repet each time CRUD methods)
#PersistenceContext(unitName = "XXXX")
private EntityManager entityManager;
This should be done in each concrete class, the abstract one should implement the concrete operation using
getEntityManager().doSomething(entity)
the getter getEntityManager() being abstract.
Imho this is a design smell, EntityManager is already an abstraction and you have nothing to gain encapsulating it.
[edit]
Regarding the "factory" approach, the way in CDI to dynamically inject resources is using producer methods.
You can so create a method returning an EntityManager instance that will dynamically resolve the EntityManagerFactory according to the persistence unit name (see an example here).
Note that this is a very bad idea as the entityManager scope is usually bound to the transaction one, letting the container inject you the entityManager instance guarantee that the scope will be correctly handled (by the container). The only viable configuration with this approach is when you want an "application managed" entityManager
NB: note that the given example will instantiate a new EntityManageFactory instance for each injection which can be really catastrophic according to the way you use it (the EntityManageFactory should be created once for all the application)
be sure to be aware of EntityManager lifecycle before going further.
Thank you guy for your advices in fact i was totally stupid in my genericDao i simply put
public abstract class GenericDao implements IGenericDao {
#PersistenceContext
private EntityManager entityManager;
As we have only one PersistentUnit it will be automatically injected....
was so easy !
then i can use #PersistentContext in all DAOs or simply and best call getEntityManager from their parent IGenericDao

Mocking vert.x application with PowerMockito

I'm trying to test my verticle but with mocked MongoDB (not to perform real DB actions during the process of unit testing), I've tried to mock my client, but looks like when I use vertx.deployVerticle() my mocks are not being taken into account.
Here's an example of my test setup:
#RunWith(VertxUnitRunner.class)
#PrepareForTest({ MongoClient.class })
public class VerticleTest {
#Rule
public PowerMockRule rule = new PowerMockRule();
private Vertx vertx;
private Integer port;
#Before
public void setUp(TestContext context) throws Exception {
vertx = Vertx.vertx();
mockStatic(MongoClient.class);
MongoClient mongo = Mockito.mock(MongoClientImpl.class);
when(MongoClient.createShared(any(), any())).thenReturn(mongo);
ServerSocket socket = new ServerSocket(0);
port = socket.getLocalPort();
socket.close();
DeploymentOptions options = new DeploymentOptions().setConfig(new JsonObject().put("http.port", port));
vertx.deployVerticle(TalWebVerticle.class.getName(), options, context.asyncAssertSuccess());
}
And what I actually see, that is that MongoClient.createShared is still being called, though I've mocked it.
What can I do in this case?
Edit 1.
Looks like the problem is that MongoClient is an interface and PowerMockito is not able to mock static methods in this case.
I'm still trying to find workaround for this case.
I didn't know that the MongoClient is an interface then I gave my first answer.
PowerMock doesn't supports mocking static calls interfaces (bug #510, Javaassist fixed exception, but mocking static methods still isn't supported). It will be called in next release.
I was focusing on issue in PowerMock, not why it's needed. I agree with answer which was provided in Mailing List.
You could work around it by creating a helper method in your own code
that returns MongoClient.createdShared(). Then in your test, mock that
helper to return your mocked MongoClientImp
But it will be not a work around, but right design solution. Mocking MongoClient is not a good approach, because you should not mock types you don't own.
So better way will be create a custom helper which will create MongoClientfor you and then mock this the helper in unit test. Also you will need integration tests for this helper which will call real MongoClient.createdShared().
If you don't have an opportunity to change code (or you don't want to change code without tests), then I've create an example with work around how PowerMock bug could be bypassed.
Main ideas:
create a custom MainMockTransformer. The transformer will transform interfaces classes to enable supporting mock static calls for interfaces
create a custom PowerMockRunner which will be used to add the custom MockTransformer to transformers chains.
Please, bring to notice on packages name where these new classes are located. It's important. If you want to move them into another packages then you will need to add these new packages to #PowerMockIgnore.

How to make #EJB injection work on the server?

Looking at this answer, it says:
If you don't want to use an Application Client Container and instead just run the application client class through a java command, injection won't be possible and you'll have to perform a JNDI lookup.
However, given that I am trying to inject a DAO bean like the example shown here, if I cannot do the automatic injecting, it means my application must manually do the JNDI lookup and all the transaction begin/end that I would get for free if the #EJB actually worked.
However, since everything is all within the same Eclipse EJB Project (it also failed with the same null handle when I had my client code in a Dynamic Web Project), surely there must be an easy way to get it all working? Can anyone suggest what I am doing wrong?
Finally, this article suggests that DAOs are not needed, but if I replace within my EJB:
#EJB MyDao dao;
with the more direct:
#PersistenceContext private EntityManager em;
I still get the similar null value; is this the same injection failure problem?
NB: I have just noticed this answer:
This is a bug in Glassfish (apparently in the web services stack).
I am running v4.0 Build 89, which still has this bug? Does this mean I have to do all JPA actions the long-winded way?
I eventually found out that the problem/issue is that in order to use injection of the #PersistenceContext the class MUST be a bean itself. This is hinted at in the example on Wikipedia:
#Stateless
public class CustomerService {
#PersistenceContext
private EntityManager entityManager;
public void addCustomer(Customer customer) {
entityManager.persist(customer);
}
}
I could delete this question, but perhaps leaving this answer might provide a hint to someone, or at least show them a minimal working example of EJB and JPA.

How to call constructor with interface arguments when mocking a concrete class with Moq

I have the following class, which uses constructor injection:
public class Service : IService
{
public Service(IRepository repository, IProvider provider) { ... }
}
For most methods in this class, I simply create Moq mocks for IRepository and IProvider and construct the Service. However, there is one method in the class that calls several other methods in the same class. For testing this method, instead of testing all those methods together, I want to test that the method calls those methods correctly and processes their return values correctly.
The best way to do this is to mock Service. I've mocked concrete classes with Moq before without issue. I've even mocked concrete classes that require constructor arguments with Moq without issue. However, this is the first time I've needed to pass mocked arguments into the constructor for a mocked object. Naturally, I tried to do it this way:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
However, that does not work. Instead, I get the following error:
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: My.Namespace.Service.
Could not find a constructor that would match given arguments:
Castle.Proxies.IRepository
Castle.Proxies.IProvider
This works fine if Service's constructor takes simple arguments like ints and strings, but not if it takes interfaces that I'm mocking. How do you do this?
Why are you mocking the service you are testing? If you are wishing to test the implementation of the Service class (whether that be calls to mocked objects or not), all you need are mocks for the two interfaces, not the test class.
Instead of:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
Shouldn't it be this instead?
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Service(repository.Object, provider.Object);
I realize that it is possible to mock concrete objects in some frameworks, but what is your intended purpose? The idea behind mocking something is to remove the actual implementation so that it does not influence your test. But in your question, you have stated that you wish to know that certain classes are called on properly, and then you wish to validate the results of those actions. That is undoubtedly testing the implementation, and for that reason, I am having a hard time seeing the goals of mocking the concrete object.
I had a very similar problem when my equivalent of Service had an internal constructor, so it was not visible to Moq.
I added
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
to my AssemblyInfo.cs file for the implementing project. Not sure if it is relevant, but I wanted to add a suggestion on the off chance that it helps you or someone else.
It must be old version issue, all is ok with latest version. Nick, Please check!
P.s.: I started bounty by misstake (I had wrong signature in my constructor).

CDI & JPA: Best scope for repository classes

I'm wondering what would be the most efficient (in terms of needed resources) scope for a repository class in CDI. Imagine the following scenario:
#RequestScoped
//OR #ApplicationScoped OR #SessionScoped OR #ConversationScoped?
public class SomeRepository{
#Inject
private EntityManager em;
public SomeClass getSomeClassById(int id){
return em.createNamedQuery("getSomeClassById",SomeClass.class).
setParameter("id",id).getSingleResult();
}
}
The EntityManager in ths example is produced with a #RequestScoped scope.
Interesting question I think. Unexpectedly I can't think of anything that makes these classes special. So I would make them #ApplicationScoped as a new instance would function exactly the same as the one I just discarded. Not sure it would have any noticeable impact on the heap, probably not but maybe if they had to be recreated a lot?
I think it's fine to go with what conceptually feels more right for you.