2
votes

I am using Quarkus with Hibernate-ORM PanacheRepository and I need to mock the PanacheQuery. I have the following classes:

  • Label(JPA Entity)
  • LabelRepository (implements PanacheRepository< Label > {})

In my test class I need to mock the labelRepository.find("name", name). This method return a PanacheQuery but I don't know how I can create a new PanacheQuery mock.

@QuarkusTest
class LabelResourceTest {

  @Inject LabelResource labelResource;
  @InjectMock LabelRepository labelRepository;

  private Label label;
  private List<Label> labels;

  @BeforeEach
  void setUp() {
    label = new Label();
    label.setId(1L);
    label.setName("LABEL#01");
    label.setInheritable(true);

    labels = new ArrayList<>();
    labels.add(label);
  }

 @Test
 void getNameTest() {
  when(labelRepository.find("name", "LABEL#01")).thenReturn(......);

 .....

 }
}

Thank you.

2

2 Answers

1
votes

This is a very good point !

Today, there is no easy way to mock a PanacheQuery. Depending on the Panache flavor, a PanacheQuery is backed with a JPA Query (for Hibernate) or a BSON Query (for MongoDB) and have the capability to act on this query object (for example, paginate).

As of today, you may need to create a Mock on the PanacheQuery interface and return this mock on your when(labelRepository.find("name", "LABEL#01")).thenReturn(......);.

Assuming you're using only the PanacheQuery.page() and the PanacheQuery.list() methods something like this (not tested should work):

PanacheQuery query = Mockito.mock(PanacheQuery.class);
Mockito.when(query.page(Mockito.any()).thenReturn(query);
Mockito.when(query.list()).thenReturn(labels);

I'll open an issue on Quarkus, maybe we can do better (provide a MockQuery) or maybe we should at least document this.

Another solution would be to encapsulate the various calls you make to the PanacheQuery object in a dedicated method inside your entity and mock this one like in this example: https://quarkus.io/guides/hibernate-orm-panache#adding-entity-methods

1
votes

The final working piece of code (thanks to @loicmathieu):

PanacheQuery query = Mockito.mock(PanacheQuery.class);
 
Mockito.when(query.page(Mockito.any())).thenReturn(query);
 
Mockito.when(query.firstResultOptional()).thenReturn(Optional.of(label));
 
when(labelRepository.find("name", "LABEL#01")).thenReturn(query);

I my case I have used the firstResultOptional() method but you can replace it if you need to use the list() because you are getting the entire list and not only a single item.