Rom*_*las 7 java generics spring spring-mvc
我为一些Spring MVC控制器编写了JUnit测试.JUnit测试的初始化对于我的所有Controllers测试都是通用的,所以我想创建一个执行此初始化的抽象类.
因此,我创建了以下代码:
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
我的想法是创建,为每个控制器我想测试一个扩展我的JUnit测试类AbstractSpringMVCControllerTest.extends声明中给出的类型是Controller的类.
例如,如果我想测试我的AccountController,我会创建这样的AccountControllerTest类:
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);
...
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题位于initContext()抽象类方法的最后一行.这个抽象类将controller对象声明为一个T对象,但是怎么能说Spring Application Context返回类型的bean T呢?
我尝试过类似的东西:
Class<?> controllerClass = this.getClass().getSuperclass().getDeclaredField("controller").getType();
controller = (T) applicationContext.getBean(controllerClass);
Run Code Online (Sandbox Code Playgroud)
但controllerClass返回java.lang.Object.class课程,而不是AccountController.class.
当然,我可以创建一个public abstract Class<?> getControllerClass();方法,它将被每个JUnit Controller测试类覆盖,但我更喜欢避免这个解决方案.
那么,任何想法?
如果您在编译时AbstractSpringMVCControllerTest绑定子类,这是可能的。T也就是说,你有类似的东西
public class DerpControllerTest extends AbstractSpringMVCControllerTest<DerpController> { }
Run Code Online (Sandbox Code Playgroud)
而不是
public class AnyControllerTest<T> extends AbstractSpringMVCControllerTest<T> { }
Run Code Online (Sandbox Code Playgroud)
我猜你可能有前者。在这种情况下, of 的类型会在运行时从for 对象T中删除,但for 对象确实提供了一种了解其类型的方法,因为它在编译时绑定。ClassAbstractSpringMVCControllerTestClassDerpControllerTest TT
以下类演示了如何访问 的类型T:
超级java
import java.lang.reflect.ParameterizedType;
public abstract class Super<T> {
protected T object;
@SuppressWarnings("unchecked")
public Class<T> getObjectType() {
// This only works if the subclass directly subclasses this class
return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}
Run Code Online (Sandbox Code Playgroud)
java子程序
public class Sub extends Super<Double> {
}
Run Code Online (Sandbox Code Playgroud)
测试.java
public class Test {
public static void main(String...args) {
Sub s = new Sub();
System.out.println(s.getObjectType()); // prints "Class java.lang.Double"
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1356 次 |
| 最近记录: |