quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.35k stars 2.56k forks source link

Improve PanacheQuery mocking #13251

Open loicmathieu opened 3 years ago

loicmathieu commented 3 years ago

Description Reading our current documentation, it is not evident how to mock a PanacheQuery object.

On the following SO question I proposes the following solution, that is a little verbose:

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

Implementation ideas Document the propose solution inside the Mock section of all Panache guide.

Or provides an easy way to mock a PanacheQuery (via a list backed PanacheQuery implementation for example, but as there a different PanacheQuery for MongoDB, Hibenrate, Kotlin, reactive, ... this canbe hard to implement).

ghost commented 3 years ago

/cc @FroMage, @Sanne, @evanchooly, @gsmet

gscaramuzzino commented 3 years ago

I agree with @loicmathieu to introduce an easy way to mock the PanacheQuery implementation or directly a Mock for PanacheRepository.

In my case I need to test the .find() of my PanacheRepository

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);

Link to the StackOverlow issue: https://stackoverflow.com/questions/64765163/how-to-mock-panachequeryentity-using-quarkus-with-hibernate-omr-panachereposit?answertab=active#tab-top

FroMage commented 3 years ago

I still think it's better to use an in-memory DB rather than mock the entities, but if you really must, then I agree that we could add public static <T> PanacheQuery fromResults(List<T> results) to every variant of PanacheQuery to make this easier.

acasanova99 commented 1 year ago

Instead of using Mockito.mock(), you might use @InjectMock

  @InjectMock
  private TRepository tRepository;

  @BeforeAll
  public void setup() {
    Mockito.when(tRepository.tMethod(anyString(), anyString())).thenReturn(
        <anything>
    );
  }
Jaland commented 4 months ago

Just adding my voice I think it would be really nice if there was just a simple way to mock a .find().

And regardless of the folks who think an in-memory db is the better option there are lots of reasons that may not be possible or easily implementable for a unit test, so having a way I can mock exactly what I want the output of a query to be should be a pretty basic feature.

FroMage commented 4 months ago

So, what do you think of this proposed solution?

Mockito.when(labelRepository.find("name", "LABEL#01")).thenReturn(PanacheQuery.fromResults(label));