Escribo pruebas de JUnit para algunos controladores Spring MVC. La inicialización de la prueba JUnit es común para todas mis pruebas de Controladores, así que quería crear una clase abstracta que realice esta inicialización.¿Cómo obtener la clase de un campo de tipo T?
Por lo tanto, he creado el siguiente código:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:spring/applicationContext-test.xml", "classpath*:spring/spring-mvc-test.xml" })
@Transactional
public abstract class AbstractSpringMVCControllerTest<T> {
@Autowired
protected ApplicationContext applicationContext;
protected MockHttpServletRequest request;
protected MockHttpServletResponse response;
protected HandlerAdapter handlerAdapter;
protected T controller;
@SuppressWarnings("unchecked")
@Before
public void initContext() throws SecurityException, NoSuchFieldException {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
handlerAdapter = applicationContext.getBean(AnnotationMethodHandlerAdapter.class);
// Does not work, the problem is here...
controller = applicationContext.getBean(T);
}
}
La idea es crear, para cada controlador Quiero probar una clase de prueba unitaria que se extiende mi AbstractSpringMVCControllerTest
. El tipo proporcionado en la declaración extends
es la clase del controlador .
Por ejemplo, si quiero probar mi AccountController
, voy a crear la clase AccountControllerTest
así:
public class AccountControllerTest extends AbstractSpringMVCControllerTest<AccountController> {
@Test
public void list_accounts() throws Exception {
request.setRequestURI("/account/list.html");
ModelAndView mav = handlerAdapter.handle(request, response, controller);
...
}
}
Mi problema se encuentra en la última línea del método de la clase abstracta initContext()
. Esta clase abstracta declara el objeto controller
como un objeto T
, pero ¿cómo puede decir al Contexto de la aplicación Spring que devuelva el bean del tipo T
?
He intentado algo así:
Class<?> controllerClass = this.getClass().getSuperclass().getDeclaredField("controller").getType();
controller = (T) applicationContext.getBean(controllerClass);
pero controllerClass
devuelve la clase java.lang.Object.class
, no AccountController.class
.
Por supuesto, puedo crear un método public abstract Class<?> getControllerClass();
, que será reemplazado por cada clase de prueba de JUnit Controller, pero prefiero evitar esta solución.
¿Alguna idea?
Si tiene una mejor idea para el título de la pregunta, no vacile :) – romaintaz
Bienvenido a la pesadilla de borrado tipo java. –
Es imposible. Duplicado de [Obtener nombre de tipo para el parámetro genérico de clase genérica] (http://stackoverflow.com/questions/6624113/get-type-name-for-generic-parameter-of-generic-class) –