package de.flower.common.test.wicket;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import org.mockito.Mockito;
import org.mockito.internal.util.MockUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
/**
* Base class for wicket test that need @SpringBean to work.
* Wicket components will get mockito mocks injected whenever
* a @SpringBean annotation is evaluated.
*
* @author flowerrrr
* @SpringBean can also be used in the test classes.
*/
public abstract class AbstractWicketMockitoTests {
protected final Logger log = LoggerFactory.getLogger(getClass());
protected WicketTester wicketTester;
protected MockitoFactoryApplicationContext mockCtx;
@BeforeMethod
public void init() {
mockCtx = new MockitoFactoryApplicationContext();
mockCtx.setVerboseLogging(isMockitoVerboseLogging());
wicketTester = createWicketTester(mockCtx);
WebApplication webApp = wicketTester.getApplication();
SpringComponentInjector injector = new SpringComponentInjector(webApp, mockCtx);
webApp.getComponentInstantiationListeners().add(injector);
// support for @SpringBean and inject mock beans into test classes.
// need pass paramater wrapInProxy 'false', cause mockito complains about proxied mocks (SpringComponentInjector wraps
// a proxy around the inject bean by default).
SpringComponentInjector testClassInjector = new SpringComponentInjector(webApp, mockCtx, false);
SpringComponentInjectorUtils.resetAllBeans(this, testClassInjector);
testClassInjector.inject(this);
}
protected boolean isMockitoVerboseLogging() {
return false;
}
protected WicketTester createWicketTester(final MockitoFactoryApplicationContext mockCtx) {
return new WicketTester();
}
@AfterMethod
public void cleanup() {
Mockito.validateMockitoUsage();
// must reset mocks to simulate destruction of app context. required when assigning mocks to class fields.
// wickets SpringComponentInjector does not reset injected fields between test methods.
resetMocks(mockCtx);
}
public static void resetMocks(MockitoFactoryApplicationContext context) {
MockUtil mockUtil = new MockUtil();
for (String name : context.getBeans().keySet()) {
Object bean = context.getBean(name);
if (mockUtil.isMock(bean)) {
Mockito.reset(bean);
}
}
}
}