Skip to content

Commit

Permalink
Merge pull request #16313 from FroMage/16182
Browse files Browse the repository at this point in the history
Support mocking PanacheEntityBase.persist static methods
  • Loading branch information
gsmet authored Apr 13, 2021
2 parents f1e177f + 6c781bd commit 1bb72b4
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@ public static long delete(String query, Parameters params) {
* @see #persist(Stream)
* @see #persist(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static void persist(Iterable<?> entities) {
JpaOperations.INSTANCE.persist(entities);
}
Expand All @@ -739,6 +740,7 @@ public static void persist(Iterable<?> entities) {
* @see #persist(Iterable)
* @see #persist(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static void persist(Stream<?> entities) {
JpaOperations.INSTANCE.persist(entities);
}
Expand All @@ -751,6 +753,7 @@ public static void persist(Stream<?> entities) {
* @see #persist(Stream)
* @see #persist(Iterable)
*/
@GenerateBridge(callSuperMethod = true)
public static void persist(Object firstEntity, Object... entities) {
JpaOperations.INSTANCE.persist(firstEntity, entities);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@ public static Uni<Long> delete(String query, Parameters params) {
* @see #persist(Stream)
* @see #persist(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> persist(Iterable<?> entities) {
return INSTANCE.persist(entities);
}
Expand All @@ -716,6 +717,7 @@ public static Uni<Void> persist(Iterable<?> entities) {
* @see #persist(Iterable)
* @see #persist(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> persist(Stream<?> entities) {
return INSTANCE.persist(entities);
}
Expand All @@ -729,6 +731,7 @@ public static Uni<Void> persist(Stream<?> entities) {
* @see #persist(Stream)
* @see #persist(Iterable)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> persist(Object firstEntity, Object... entities) {
return INSTANCE.persist(firstEntity, entities);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,7 @@ public static long delete(Document query) {
* @see #persist(Stream)
* @see #persist(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static void persist(Iterable<?> entities) {
INSTANCE.persist(entities);
}
Expand All @@ -784,6 +785,7 @@ public static void persist(Iterable<?> entities) {
* @see #persist(Iterable)
* @see #persist(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static void persist(Stream<?> entities) {
INSTANCE.persist(entities);
}
Expand All @@ -796,6 +798,7 @@ public static void persist(Stream<?> entities) {
* @see #persist(Stream)
* @see #persist(Iterable)
*/
@GenerateBridge(callSuperMethod = true)
public static void persist(Object firstEntity, Object... entities) {
INSTANCE.persist(firstEntity, entities);
}
Expand All @@ -808,6 +811,7 @@ public static void persist(Object firstEntity, Object... entities) {
* @see #update(Stream)
* @see #update(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static void update(Iterable<?> entities) {
INSTANCE.update(entities);
}
Expand All @@ -820,6 +824,7 @@ public static void update(Iterable<?> entities) {
* @see #update(Iterable)
* @see #update(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static void update(Stream<?> entities) {
INSTANCE.update(entities);
}
Expand All @@ -832,6 +837,7 @@ public static void update(Stream<?> entities) {
* @see #update(Stream)
* @see #update(Iterable)
*/
@GenerateBridge(callSuperMethod = true)
public static void update(Object firstEntity, Object... entities) {
INSTANCE.update(firstEntity, entities);
}
Expand All @@ -844,6 +850,7 @@ public static void update(Object firstEntity, Object... entities) {
* @see #persistOrUpdate(Stream)
* @see #persistOrUpdate(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static void persistOrUpdate(Iterable<?> entities) {
INSTANCE.persistOrUpdate(entities);
}
Expand All @@ -856,6 +863,7 @@ public static void persistOrUpdate(Iterable<?> entities) {
* @see #persistOrUpdate(Iterable)
* @see #persistOrUpdate(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static void persistOrUpdate(Stream<?> entities) {
INSTANCE.persistOrUpdate(entities);
}
Expand All @@ -868,6 +876,7 @@ public static void persistOrUpdate(Stream<?> entities) {
* @see #persistOrUpdate(Stream)
* @see #persistOrUpdate(Iterable)
*/
@GenerateBridge(callSuperMethod = true)
public static void persistOrUpdate(Object firstEntity, Object... entities) {
INSTANCE.persistOrUpdate(firstEntity, entities);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,7 @@ public static Uni<Long> delete(Document query) {
* @see #persist(Stream)
* @see #persist(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> persist(Iterable<?> entities) {
return INSTANCE.persist(entities);
}
Expand All @@ -797,6 +798,7 @@ public static Uni<Void> persist(Iterable<?> entities) {
* @see #persist(Iterable)
* @see #persist(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> persist(Stream<?> entities) {
return INSTANCE.persist(entities);
}
Expand All @@ -809,6 +811,7 @@ public static Uni<Void> persist(Stream<?> entities) {
* @see #persist(Stream)
* @see #persist(Iterable)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> persist(Object firstEntity, Object... entities) {
return INSTANCE.persist(firstEntity, entities);
}
Expand All @@ -821,6 +824,7 @@ public static Uni<Void> persist(Object firstEntity, Object... entities) {
* @see #update(Stream)
* @see #update(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> update(Iterable<?> entities) {
return INSTANCE.update(entities);
}
Expand All @@ -833,6 +837,7 @@ public static Uni<Void> update(Iterable<?> entities) {
* @see #update(Iterable)
* @see #update(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> update(Stream<?> entities) {
return INSTANCE.update(entities);
}
Expand All @@ -845,6 +850,7 @@ public static Uni<Void> update(Stream<?> entities) {
* @see #update(Stream)
* @see #update(Iterable)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> update(Object firstEntity, Object... entities) {
return INSTANCE.update(firstEntity, entities);
}
Expand All @@ -857,6 +863,7 @@ public static Uni<Void> update(Object firstEntity, Object... entities) {
* @see #persistOrUpdate(Stream)
* @see #persistOrUpdate(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> persistOrUpdate(Iterable<?> entities) {
return INSTANCE.persistOrUpdate(entities);
}
Expand All @@ -869,6 +876,7 @@ public static Uni<Void> persistOrUpdate(Iterable<?> entities) {
* @see #persistOrUpdate(Iterable)
* @see #persistOrUpdate(Object,Object...)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> persistOrUpdate(Stream<?> entities) {
return INSTANCE.persistOrUpdate(entities);
}
Expand All @@ -881,6 +889,7 @@ public static Uni<Void> persistOrUpdate(Stream<?> entities) {
* @see #persistOrUpdate(Stream)
* @see #persistOrUpdate(Iterable)
*/
@GenerateBridge(callSuperMethod = true)
public static Uni<Void> persistOrUpdate(Object firstEntity, Object... entities) {
return INSTANCE.persistOrUpdate(firstEntity, entities);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public void visitEnd() {
if (!userMethods.contains(method.name() + "/" + descriptor)) {
AnnotationInstance bridge = method.annotation(PanacheConstants.DOTNAME_GENERATE_BRIDGE);
if (bridge != null) {
generateMethod(method, bridge.value("targetReturnTypeErased"));
generateMethod(method, bridge.value("targetReturnTypeErased"), bridge.value("callSuperMethod"));
}
}
}
Expand Down Expand Up @@ -144,7 +144,7 @@ protected void discoverTypeParameters(ClassInfo classInfo, IndexView indexView,
}
}

protected void generateMethod(MethodInfo method, AnnotationValue targetReturnTypeErased) {
protected void generateMethod(MethodInfo method, AnnotationValue targetReturnTypeErased, AnnotationValue callSuperMethod) {
List<org.jboss.jandex.Type> parameters = method.parameters();

MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC,
Expand All @@ -157,9 +157,17 @@ protected void generateMethod(MethodInfo method, AnnotationValue targetReturnTyp
for (PanacheMethodCustomizer customizer : methodCustomizers) {
customizer.customize(thisClass, method, mv);
}
loadOperations(mv);
loadArguments(mv, parameters);
invokeOperations(mv, method);
if (callSuperMethod != null && callSuperMethod.asBoolean()) {
// delegate to super method
for (int i = 0; i < parameters.size(); i++) {
mv.visitIntInsn(Opcodes.ALOAD, i);
}
invokeOperations(mv, method, true);
} else {
loadOperations(mv);
loadArguments(mv, parameters);
invokeOperations(mv, method, false);
}
mv.visitMaxs(0, 0);
mv.visitEnd();
}
Expand All @@ -177,11 +185,13 @@ private void loadArguments(MethodVisitor mv, List<org.jboss.jandex.Type> paramet
}
}

private void invokeOperations(MethodVisitor mv, MethodInfo method) {
private void invokeOperations(MethodVisitor mv, MethodInfo method, boolean callSuperMethod) {
String operationDescriptor;

StringJoiner joiner = new StringJoiner("", "(", ")");
joiner.add(CLASS.descriptor());
if (!callSuperMethod) {
joiner.add(CLASS.descriptor());
}
descriptors(method, joiner);

org.jboss.jandex.Type returnType = method.returnType();
Expand All @@ -191,9 +201,15 @@ private void invokeOperations(MethodVisitor mv, MethodInfo method) {
: returnType.name().toString();
operationDescriptor = joiner + erasures.getOrDefault(key, descriptor);

mv.visitMethodInsn(INVOKEVIRTUAL, typeBundle.operations().internalName(), method.name(),
operationDescriptor, false);
if (returnType.kind() != org.jboss.jandex.Type.Kind.PRIMITIVE) {
if (callSuperMethod) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, typeBundle.entityBase().internalName(), method.name(),
operationDescriptor, false);
} else {
mv.visitMethodInsn(INVOKEVIRTUAL, typeBundle.operations().internalName(), method.name(),
operationDescriptor, false);
}
if (returnType.kind() != org.jboss.jandex.Type.Kind.PRIMITIVE
&& returnType.kind() != org.jboss.jandex.Type.Kind.VOID) {
String cast;
if (returnType.kind() == org.jboss.jandex.Type.Kind.TYPE_VARIABLE) {
TypeVariable typeVariable = returnType.asTypeVariable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@
*/
boolean targetReturnTypeErased() default false;

/**
* Set to true to delegate to the super method instead of JpaOperations. This is useful to
* still inject interceptor calls and mock stubs.
*/
boolean callSuperMethod() default false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public void testPanacheMocking() {
Assertions.assertSame(p, Person.findById(12l));
Assertions.assertNull(Person.findById(42l));

Person.persist(p);
Assertions.assertNull(p.id);

Mockito.when(Person.findById(12l)).thenThrow(new WebApplicationException());
try {
Person.findById(12l);
Expand All @@ -89,6 +92,7 @@ public void testPanacheMocking() {

PanacheMock.verify(Person.class, Mockito.atLeast(5)).voidMethod();
PanacheMock.verify(Person.class).findOrdered();
PanacheMock.verify(Person.class).persist(Mockito.<Object> any(), Mockito.<Object> any());
PanacheMock.verify(Person.class, Mockito.atLeastOnce()).findById(Mockito.any());
PanacheMock.verifyNoMoreInteractions(Person.class);

Expand Down Expand Up @@ -124,6 +128,9 @@ public void testPanacheRepositoryMocking() throws Throwable {
Assertions.assertSame(p, mockablePersonRepository.findById(12l));
Assertions.assertNull(mockablePersonRepository.findById(42l));

mockablePersonRepository.persist(p);
Assertions.assertNull(p.id);

Mockito.when(mockablePersonRepository.findById(12l)).thenThrow(new WebApplicationException());
try {
mockablePersonRepository.findById(12l);
Expand All @@ -136,6 +143,7 @@ public void testPanacheRepositoryMocking() throws Throwable {

Mockito.verify(mockablePersonRepository).findOrdered();
Mockito.verify(mockablePersonRepository, Mockito.atLeastOnce()).findById(Mockito.any());
Mockito.verify(mockablePersonRepository).persist(Mockito.<Person> any());
Mockito.verifyNoMoreInteractions(mockablePersonRepository);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public void testPanacheMocking() {
Assertions.assertSame(p, Person.findById(12l).await().indefinitely());
Assertions.assertNull(Person.findById(42l).await().indefinitely());

Person.persist(p).await().indefinitely();
Assertions.assertNull(p.id);

Mockito.when(Person.findById(12l)).thenThrow(new WebApplicationException());
try {
Person.findById(12l);
Expand All @@ -54,6 +57,7 @@ public void testPanacheMocking() {
Assertions.assertTrue(Person.findOrdered().await().indefinitely().isEmpty());

PanacheMock.verify(Person.class).findOrdered();
PanacheMock.verify(Person.class).persist(Mockito.<Object> any(), Mockito.<Object> any());
PanacheMock.verify(Person.class, Mockito.atLeastOnce()).findById(Mockito.any());
PanacheMock.verifyNoMoreInteractions(Person.class);

Expand Down Expand Up @@ -89,6 +93,9 @@ public void testPanacheRepositoryMocking() throws Throwable {
Assertions.assertSame(p, mockablePersonRepository.findById(12l).await().indefinitely());
Assertions.assertNull(mockablePersonRepository.findById(42l).await().indefinitely());

mockablePersonRepository.persist(p).await().indefinitely();
Assertions.assertNull(p.id);

Mockito.when(mockablePersonRepository.findById(12l)).thenThrow(new WebApplicationException());
try {
mockablePersonRepository.findById(12l);
Expand All @@ -101,6 +108,7 @@ public void testPanacheRepositoryMocking() throws Throwable {

Mockito.verify(mockablePersonRepository).findOrdered();
Mockito.verify(mockablePersonRepository, Mockito.atLeastOnce()).findById(Mockito.any());
Mockito.verify(mockablePersonRepository).persist(Mockito.<Person> any());
Mockito.verifyNoMoreInteractions(mockablePersonRepository);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.quarkus.it.mongodb.panache.reactive.person;

import java.util.List;

import javax.enterprise.context.ApplicationScoped;

import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepositoryBase;
import io.quarkus.panache.common.Sort;
import io.smallrye.mutiny.Uni;

@ApplicationScoped
public class MockableReactivePersonRepository implements ReactivePanacheMongoRepositoryBase<ReactivePersonEntity, Long> {
public Uni<List<ReactivePersonEntity>> findOrdered() {
return findAll(Sort.by("lastname", "firstname")).list();
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package io.quarkus.it.mongodb.panache.reactive.person;

import java.util.List;

import org.bson.codecs.pojo.annotations.BsonId;

import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoEntityBase;
import io.quarkus.panache.common.Sort;
import io.smallrye.mutiny.Uni;

public class ReactivePersonEntity extends ReactivePanacheMongoEntityBase {
@BsonId
public Long id;
public String firstname;
public String lastname;

public static Uni<List<ReactivePersonEntity>> findOrdered() {
return findAll(Sort.by("lastname", "firstname")).list();
}
}
Loading

0 comments on commit 1bb72b4

Please sign in to comment.