我在网上做了很多搜索,找不到一个使用自动布线构造函数进行单元测试的例子。我正在使用Spring将属性文件中的值自动装入到我的应用程序中。我想单元测试MyApp.java的启动方法,但我有一个自动装配的构造函数,所以我不知道如何实例化MyApp。如果没有自动装配性能,我在我的单元测试这样做:如何JUnit测试Spring自动布线构造函数?
@Test
public void testStart() {
try{
MyApp myApp = new MyApp();
myApp.start();
}
catch (Exception e){
fail("Error thrown")
}
}
我不想嘲笑自动装配,因为我需要从属性文件,并进一步复杂化的东西来获得价值,我通过注释配置所有内容。我没有spring.xml,application-context.xml或web.xml文件。那么我该如何去实例化/测试MyApp的启动方法呢?我尝试在@RunWith(SpringJUnit4ClassRunner.class)中添加并自动装配MyApp myApp,但它会抛出有关未能通过在测试类上实现ApplicationContextAware来解决的应用程序上下文失败的错误。
这里是MyApp.java
@Component
public class MyApp {
private static ApplicationContext applicationContext;
private static MyAppProperties myAppProperties;
//Obtain the values from the app.properties file
@Autowired
MyApp(MyAppProperties myAppProps){
myAppProperties = myAppProps;
}
public static void main(String[] args) throws Exception {
// Instantiate the application context for use by the other classes
applicationContext = new AnnotationConfigApplicationContext("com.my.company");
start();
}
/**
* Start the Jetty server and configure the servlets
*
* @throws Exception
*/
public static void start() throws Exception {
// Create Embedded Jetty server
jettyServer = new Server();
// Configure Jetty so that it stops at JVM shutdown phase
jettyServer.setStopAtShutdown(true);
jettyServer.setStopTimeout(7_000);
// Create a list to hold all of the handlers
final HandlerList handlerList = new HandlerList();
// Configure for Http
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSecureScheme("https");
http_config.setSecurePort(myAppProperties.getHTTP_SECURE_PORT());
....
}
}
这里是我的app.properties文件
# Spring Configuration for My application
#properties for the embedded jetty server
http_server_port=12345
这里是MyAppProperties.java
@Component
public class MyAppProperties implements ApplicationContextAware {
private ApplicationContext applicationContext;
//List of values from the properties files to be autowired
private int HTTP_SERVER_PORT;
...
@Autowired
public MyAppProperties(@Value("${http_server_port}") int http_server_port, ...){
this.HTTP_SERVER_PORT = http_server_port;
}
/**
* @return the applicationContext
*/
public ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* @param applicationContext
* the applicationContext to set
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* @param name
* the name to set
*/
public void setHTTP_SERVER_PORT(String name) {
JETTY_SERVER_NAME = name;
}
/**
* @return the httpServerPort
*/
public int getHTTP_SERVER_PORT() {
return HTTP_SERVER_PORT;
}
}
这里是MyAppTest.java
@RunWith(SpringJUnit4ClassRunner.class)
public class MyAppTest implements ApplicationContextAware{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext appContext) {
applicationContext = appContext;
}
@Autowired
private MyApp myapp;
@Test
public void testStart(){
try {
if(myapp != null){
myapp.start();
}
else{
fail("myapp is null");
}
} catch (Exception e) {
fail("Error thrown");
e.printStackTrace();
}
}
}
更新:这里是我的配置类
@Configuration
@Component
public class ApplicationConfig implements ApplicationContextAware {
private final Logger LOGGER = LoggerFactory.getLogger(ApplicationConfig.class);
private ApplicationContext applicationContext;
/**
* @return the applicationContext
*/
public ApplicationContext getApplicationContext() {
LOGGER.debug("Getting Application Context", applicationContext);
return applicationContext;
}
/**
* @param applicationContext
* the applicationContext to set
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
// Needed for @Value
/**
* Property sources placeholder configurer.
*
* @return the property sources placeholder configurer
*/
@Bean
public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() {
PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
propertyPlaceholderConfigurer.setLocation(new ClassPathResource("app.properties"));
return propertyPlaceholderConfigurer;
}
...
}
仅添加'@ RunWith'并且不告知要加载哪个配置将会失败。你必须在你的测试类中添加一个'public static class',在其上放置'@ Configuration'和'@ComponentScan(“your.package”)''。在更进一步的层面上,我会建议使用Spring Boot来引导应用程序并注入/使用属性,因为您似乎在做Spring Boot提供的开箱即用(包括测试支持)。 –
@ M.Deinum不幸的是,由于与其他工具的冲突,Spring Boot不适合我。只是为了澄清你说我应该改变我的测试类是公共静态类MyAppTest还是我应该做另一个类?当我尝试使MyAppTest类静态时,我收到一条错误消息,指出它是非法修饰符。 – jencoston
不,您需要添加内部配置类。另外,我并没有发现Spring Boot在与你自己一样笑内部服务器时会有什么不同,应该没有什么区别。 –