gpt4 book ai didi

spring - 如何 JUnit 测试 Spring Autowiring 构造函数?

转载 作者:行者123 更新时间:2023-12-02 04:16:14 25 4
gpt4 key购买 nike

我在网上进行了大量搜索,但找不到使用 Autowiring 构造函数进行单元测试的示例。我正在使用 Spring 将属性文件中的值自动连接到我的应用程序。我想对 MyApp.java 的 start 方法进行单元测试,但我有一个 Autowiring 的构造函数,所以我不知道如何实例化 MyApp。如果没有 Autowiring 属性,我在单元测试中执行此操作:

@Test
public void testStart() {
try{
MyApp myApp = new MyApp();
myApp.start();
}
catch (Exception e){
fail("Error thrown")
}
}

我不想模拟 Autowiring ,因为我需要从属性文件中获取值,并且使事情进一步复杂化,我通过注释配置所有内容。我没有 spring.xml、application-context.xml 或 web.xml 文件。那么我该如何实例化/测试 MyApp 的启动方法呢?我尝试添加 @RunWith(SpringJUnit4ClassRunner.class) 并 Autowiring 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;
}
...
}

最佳答案

我们可以使用 jmockito 框架模拟对象。

通过 Mockito 使用 @InjectMocks 进行依赖注入(inject)您还拥有 @InjectMocks 注释,它尝试根据类型进行构造函数、方法或字段依赖项注入(inject)。以下代码是 Javadoc 中的示例,稍作修改。

// Mockito can construct this class via constructor
public class ArticleManager {
ArticleManager(ArticleCalculator calculator, ArticleDatabase database) {
}
}

// Mockito can also perform method injection
public class ArticleManager {
ArticleManager() { }
void setDatabase(ArticleDatabase database) { }
void setCalculator(ArticleCalculator calculator) { }
}

// Mockito can also perform field injection
public class ArticleManager {

private ArticleDatabase database;
private ArticleCalculator calculator;
}

以下是单元测试类。

@RunWith(MockitoJUnitRunner.class)
public class ArticleManagerTest {
@Mock private ArticleCalculator calculator;
@Mock private ArticleDatabase database;
@Spy private UserProvider userProvider = new ConsumerUserProvider();

// creates instance of ArticleManager
// and performs constructor injection on it
@InjectMocks private ArticleManager manager;

@Test public void shouldDoSomething() {
// assume that ArticleManager has a method called initialize which calls a method
// addListener with an instance of ArticleListener
manager.initialize();

// validate that addListener was called
verify(database).addListener(any(ArticleListener.class));
}

}

确保您使用的是@RunWith(MockitoJUnitRunner.class)欲了解更多信息,请参阅http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/InjectMocks.html .

关于spring - 如何 JUnit 测试 Spring Autowiring 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37727311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com