Class SpiesHook
- java.lang.Object
-
- ru.vyarus.dropwizard.guice.test.spy.SpiesHook
-
- All Implemented Interfaces:
GuiceyConfigurationHook
public class SpiesHook extends java.lang.Object implements GuiceyConfigurationHook
Replace any guice service with mockito spy. The difference with mock: spy wraps around the real service(!) and could be used to validate called service methods (verify incoming parameters and output value).Important: requires mockito dependency!
In contrast to mocks and stubs, spies work with guice AOP: all calls to service are intercepted and passed through the spy object (as "proxy"). That also means that all aop, applied to the original bean, would work (in contrast to mocks).
As spy requires real bean instance - spy object is created just after injector creation (and AOP interceptor redirects into it (then real bean called)). Spy object is different instance as injected bean (
@Inject SpiedService) because injected bean would be a proxy, handling guice AOP.Calling bean methods directly on spy is completely normal (guice bean just redirects calls to spy object)!
Usage example:
SpiesHook hook = new SpiesHook(); SpyProxy<Service> proxy = hook.spy(Service.class) // actual spy object can be obtained only after guice application startup Service spy = proxy.getSpy() doReturn(12).when(spy).foo();Alternatively, provider might be used instead of proxy type (for simplicity):
Provider<Service> provider = hook.spy(Service.class)Spy CAN'T be initialized manually. Use
MocksHookorStubsHookinstead for manual spy objects initialization. Such manual initialization could be required for spies created from abstract classes (or multiple interfaces): in this case actual bean instance is not required, and so mocks support could be used instead:AbstractService spy = mocksHook.mock(AbstractService.class, Mockito.spy(AbstractService.class)).Actual spy object instance is created only on first bean access (after or in time of application startup). Normally, it is ok to wait for application startup, configure spy object and then run tests methods (using spy). But if spied bean is involved in application startup (called by some managed objects) then the only way to configure it is to apply modification just after spy instance creation:
hook.spy(Service.class).withInitializer(spy -> { doReturn(12).when(spy).foo() }).- Since:
- 29.04.2025
-
-
Constructor Summary
Constructors Constructor Description SpiesHook()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voidconfigure(GuiceBundle.Builder builder)Configuration is applied just after manual configuration (through bundle's builder in application class).<T> TgetSpy(java.lang.Class<T> type)voidresetSpies()Reset all registered spies.<T> SpyProxy<T>spy(java.lang.Class<T> type)Request wrapping target bean with a spy.-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface ru.vyarus.dropwizard.guice.hook.GuiceyConfigurationHook
register
-
-
-
-
Method Detail
-
configure
public void configure(GuiceBundle.Builder builder) throws java.lang.Exception
Description copied from interface:GuiceyConfigurationHookConfiguration is applied just after manual configuration (through bundle's builder in application class).GuiceBundle.Buildercontains special methods for test support:- Generic disable:
GuiceBundle.Builder.disable(java.util.function.Predicate[]) - Direct disable* method, for example
GuiceBundle.Builder.disableExtensions(Class[]) - Guice bindings override:
GuiceBundle.Builder.modulesOverride(com.google.inject.Module...)
GuiceBundle.Builder.option(Enum, Object)).All configuration items, registered with hook will be scoped as
GuiceyConfigurationHookinstead ofApplicationand so will be clearly distinguishable in configuration logs (GuiceBundle.Builder.printDiagnosticInfo()).- Specified by:
configurein interfaceGuiceyConfigurationHook- Parameters:
builder- just created bundle's builder- Throws:
java.lang.Exception- on error (simplify usage)
- Generic disable:
-
spy
public <T> SpyProxy<T> spy(java.lang.Class<T> type)
Request wrapping target bean with a spy.As spy object requires bean instance, then spy could be created only during injector startup. Returned proxy must be used to get an actual spy object after application startup (for configuration before test logic execution).
Returned proxy instance could be used for startup initializer registration:
hook.spy(Service.class).withInitializer(...)(required ONLY in cases when spy must be used during application startup and so can't be configured after application startup.Returned proxy also implements
Providerinterface, so provider could be used instead of proxy type:Provider<Service> provider = hook.spy(Service.class)For spies targeting guice beans registered by instance use mocks (
MocksHook) because in this case bean instance is not required.- Type Parameters:
T- bean type- Parameters:
type- bean type- Returns:
- spy proxy instance
-
getSpy
public <T> T getSpy(java.lang.Class<T> type)
- Type Parameters:
T- bean type- Parameters:
type- bean type- Returns:
- mockito spy object (not proxy!)
- Throws:
java.lang.IllegalStateException- if spy for bean is not registered
-
resetSpies
public void resetSpies()
Reset all registered spies.
-
-