Closed jonsalvas closed 5 months ago
/cc @gwenneg (cache), @karesti (infinispan), @wburns (infinispan)
taking the point
aside from not being able to run containers on a test environment, being able to mock infinispan would also mean faster unit tests as no container needs to ben built / started. Currently, we fix this situation by having a permanent test instance of infinispan availlable and our tests just start by wiping the caches. But this is off course not ideal since our tests now fail if for some reason that infinispan instance is down.
The beans of scope @Dependent
or @Singleton
can't be used with InjectMock
The RemoteCache
can't be ApplicationScoped
since it would break the code of Search at this moment:
QueryFactory queryFactory = Search.getQueryFactory(cache);
We need to make modifications to the Infinispan implementation to make it possible, and I'm not sure we can do that easily or without impact. We need to check this @wburns
However, RemoteCacheManager
and CounterManager
can be @ApplicationScoped
beans, even if they are @Dependent
beans now. This evolution to ApplicationScoped beans is landing here: https://github.com/quarkusio/quarkus/pull/32494
You will be able to mock getCache
and use your own RemoteCache
mocks if you use the injected RemoteCacheManager
to grab the RemoteCache
instance instead of using directly the RemoteCache
injection. In the new version, RemoteCache will be @Singleton
@ractoc @jonsalvas
@karesti I'm currently trying to implement your suggestion. This is the code I'm using atm: Service implementation:
@ApplicationScoped
public class ComponentService {
public static final String CACHE_PVB_CORE_COMP = "pvbCoreComp";
@Inject
@ApplicationScoped
RemoteCacheManager cacheManager;
public Optional<Component> findComponentById(String componentId) {
RemoteCache<String, Component> cache = cacheManager.getCache(CACHE_PVB_CORE_COMP);
return Optional.ofNullable(cache.get(componentId));
}
}
Service test implementation:
@QuarkusTest
class ComponentServiceTest {
@Inject
ComponentService service;
@InjectMock
RemoteCacheManager remoteCacheManagerMock;
@org.mockito.Mock
RemoteCache mockedCache;
@Test
void findComponentById() {
// Given
when(mockedCache.get("componentId")).thenReturn(new Component("testComponent", "testComponentId"));
when(remoteCacheManagerMock.getCache("pvbCoreComp")).thenReturn(mockedCache);
// When
Optional<Component> component = service.findComponentById("componentId");
// Then
assertThat(component)
.isNotEmpty()
.get()
.hasFieldOrPropertyWithValue("componentId", "testComponentId")
.hasFieldOrPropertyWithValue("name", "testComponent");
}
}
While I am using @InjectMock to inject my mocked RemoteCacheManager, I keep getting the error:
Cannot invoke "org.infinispan.client.hotrod.RemoteCacheManager.getCache(String)" because "this.cacheManager" is null
@ractoc I probably did not explain well. In the current extension, RemoteCacheManager is a dependant scope bean. The transformation of the RemoteCacheManager in an application scoped bean is already developed in this pull request. https://github.com/quarkusio/quarkus/pull/32494 Once the feature is merged, you will be able to inject and use it as mock
coo, yeah I can now mock my cachemanager and through that the RemoteCache itsself. Next up, trying to figure out how to make this all work with the QueryFactory...
@ractoc I'll see with the team how to improve the experience
In the end the solution was fairly simple, if a bit ugly. The only way I could really get it to work is to create a test stub for the Search object in my test code with the same package / Class as the original. Then I just have that one return my Query mock object as needed. As I said, it's ugly, but it works. The problem is, that the Search object only has 2 static methods, so they are hard to mock. This IS possible, but you need to replace the mockito-core with mockito-inline. Since the mockito-core comes from the quarkus-junit5-mockito dependency...
Hi @karesti, I created ISPN-15060 to improve the current Infinispan API to use a proxy to get query factory. Thank you for raising this issue. It is something that we need to address soon I think.
Description
Right now, when doing
I receive the following error:
It would be great if mocking of RemoteCache would be possible so that we test infispan-consuming classes.
I know you can use Dev-Server for testing, but this is not an option for us, as the CI environment does not support testcontainers.
Implementation ideas
No response